前言
我們使用linux時,終止程序一般喜歡用 kill -9 pid
命令,因為這個命令來的快,執行及終止,不需要等待。我也一直喜歡用這個命令,包括在寫一些程序關閉腳本時,也用的這個命令,其實也不是不知道這個命令的弊端,但平時做的項目太小並發不高,出現這個問題的概率太小。今天無意看到一篇文章《CTO 說了,如果發現誰用 kill -9 關閉程序就開除》,深有感觸。以下是優雅的結束springboot服務的3種方式:
什么叫優雅的結束?
第一步:停止接收請求和內部線程。
第二步:判斷是否有線程正在執行。
第三步:等待正在執行的線程執行完畢。
第四步:停止容器。
第一種:kill -15 pid
kill -15 這個命令會讓程序馬上調用線程的interrupt方法,目的是為了讓線程停止,雖然讓線程停止,但線程什么時候停止還是線程自己說的算
第二種:ConfigurableApplicationContext colse
@PostMapping(value = "shutdown")
public void shutdown(){
ConfigurableApplicationContext cyx = (ConfigurableApplicationContext) context;
cyx.close();
}
cyx.close();
,為什么他能停止springboot項目呢?
public void close() {
synchronized(this.startupShutdownMonitor) {
this.doClose();
if (this.shutdownHook != null) {
try {
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
} catch (IllegalStateException var4) {
}
}
}
}
程序在啟動的時候向jvm注冊了一個關閉鈎子,我們在執行colse方法的時候會刪除這個關閉鈎子,jvm就會知道這是需要停止服務。jvm執行了線程的interrupt方法,原理和kill -15差不多。
第三種:actuator
這種方式是通過引入依賴的方式停止服務,actuator提供了很多接口,比如健康檢查,基本信息等等,我們也可以使用他來優雅的停機。請求地址類似http:/domain/actuator/shutdown
小記
通過java代碼層面來關閉服務,不僅可以關閉服務,還可以在服務關閉前后約定一些特殊的邏輯,比如:關閉前備份一些數據、或者關閉之后發送一條郵件給運維管理員等邏輯。