您好,登錄后才能下訂單哦!
一. 前言
項(xiàng)目初期我們可以使用kill -9 pid的方法來(lái)殺死后臺(tái)服務(wù)進(jìn)程,然后重新部署。
但是隨著時(shí)間發(fā)展,這種簡(jiǎn)單粗暴的方法會(huì)有一些問(wèn)題:
如何在退出時(shí)清理一些資源?
如果某個(gè)請(qǐng)求執(zhí)行操作到一半,直接被退出了,就會(huì)造成臟數(shù)據(jù)。
如何給客戶(hù)端正確的反饋?
二. Java虛擬機(jī)退出鉤子
虛擬機(jī)允許在退出的時(shí)候執(zhí)行鉤子程序,那么我們可以在這個(gè)方法里面作一些釋放資源的操作,如下:
System.out.println("add hook..."); Thread shutdownThread = new Thread(new Runnable() { @Override public void run() { System.out.println("hook running.." + System.currentTimeMillis()); try { Thread.sleep(10000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("hook sleep done..." + System.currentTimeMillis()); } }); Runtime.getRuntime().addShutdownHook(shutdownThread);
三. tomcat的unloadDelay屬性
這個(gè)屬性的意思是tomcat留給請(qǐng)求執(zhí)行的時(shí)間,默認(rèn)只有2秒,也就是執(zhí)行./shundown.sh之后,請(qǐng)求處理只有2秒的時(shí)間。如果沒(méi)有及時(shí)返回給客戶(hù)端,那么就會(huì)返回客戶(hù)端503錯(cuò)誤。
apache-tomcat-9.0.0.M22-src/java/org/apache/catalina/core/StandardWrapper.java
/** * Wait time for servlet unload in ms. */ protected long unloadDelay = 2000; public synchronized void unload() throws ServletException { // Nothing to do if we have never loaded the instance if (!singleThreadModel && (instance == null)) { log.info("instance run..."); return; } unloading = true; log.info("countAllocated.get(): " + countAllocated.get()); // Loaf a while if the current instance is allocated // (possibly more than once if non-STM) if (countAllocated.get() > 0) { int nRetries = 0; long delay = unloadDelay / 20; System.out.println("unloadDelay: " + unloadDelay); log.info("unloadDelay 2222: " + unloadDelay); while ((nRetries < 21) && (countAllocated.get() > 0)) { if ((nRetries % 10) == 0) { log.info(sm.getString("standardWrapper.waiting", countAllocated.toString(), getName())); } try { Thread.sleep(delay); } catch (InterruptedException e) { // Ignore } nRetries++; } } }
這段代碼它會(huì)把unloadDelay分成20份,然后循環(huán)20次檢查請(qǐng)求是否已經(jīng)結(jié)束。
unloadDelay默認(rèn)是2000ms,也就是2秒鐘.
這樣寫(xiě)的好處是即使配置的unloadDelay時(shí)間很長(zhǎng),但是如果請(qǐng)求很快結(jié)束,那么它也不會(huì)等待配置的unloadDelay時(shí)間,它可以提前退出服務(wù)。
如果請(qǐng)求在unloadDelay時(shí)間內(nèi)處理完請(qǐng)求,那么客戶(hù)端就可以接受到正常的結(jié)果。
四. unloadDelay配置
在tomcat的conf目錄下的context.xml中可以配置,如下:
<Context unloadDelay="20000"> ... </Context>
五. springboot發(fā)送http請(qǐng)求關(guān)閉服務(wù)
在pom.xml中配置
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId></dependency>
在application.properties中配置
#啟用 shutdownendpoints.shutdown.enabled=true #禁用密碼驗(yàn)證 endpoints.shutdown.sensitive=false
發(fā)送http關(guān)閉命令
curl -X POST host:port/shutdown
得到的返回消息如下:
{"message":"Shutting down, bye..."}
發(fā)送http消息后,它會(huì)拒絕新的請(qǐng)求,2秒內(nèi)讓已有請(qǐng)求執(zhí)行完畢,清理資源。
六. 權(quán)限
如果沒(méi)有權(quán)限,那么任何人發(fā)送curl -X POST host:port/shundown都可以關(guān)閉服務(wù)。
所以,需要添加權(quán)限
1.pom.xml中添加申明
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
spring-boot-starter-actuator的作用參考這篇帖子:
Springboot startr作用詳解
2.appliaction.properties文件中添加用戶(hù)名和密碼
endpoints.shutdown.sensitive=true security.user.name=admin security.user.password=admin management.security.role=SUPERUSER
3.發(fā)起的http指令中攜帶用戶(hù)名和密碼
curl -uadmin:admin -X POST http://host:port/shutdown
4.不過(guò)這樣會(huì)導(dǎo)致正常的請(qǐng)求也需要用戶(hù)名和密碼,所以application.properties還得再加一句:
security.basic.enabled=false
5.IP地址驗(yàn)證
如果想另外加上IP地址驗(yàn)證,那么全部配置如下:
endpoints.shutdown.enabled=true endpoints.shutdown.sensitive=true security.basic.enabled=false #不影響正常請(qǐng)求 security.user.name=admin security.user.password=admin management.security.role=SUPERUSER management.port=3081 #管理的端口,需要和server.port不同(正常的請(qǐng)求端口) management.address=127.0.0.1 #只允許本機(jī)發(fā)送http shutdown命令
發(fā)送的指令如下:
curl -uadmin:admin -X POST http://localhost:3081/shutdown
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。