? Spring Boot 依賴與配置
Maven 依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.github.timpeeters</groupId>
<artifactId>spring-boot-graceful-shutdown</artifactId>
<version>2.1.1</version>
</dependency>
? Graceful Shutdown 配置說明
配置項(xiàng) | 默認(rèn)值 | 描述 |
---|---|---|
graceful.shutdown.enabled | false | 是否啟用優(yōu)雅停機(jī) |
graceful.shutdown.timeout | 60 | 在關(guān)閉 Tomcat Connector 之前等待活躍線程完成的秒數(shù) |
graceful.shutdown.wait | 30 | 優(yōu)雅停機(jī)前,服務(wù)處于 OUT_OF_SERVICE 的時(shí)間 |
? Graceful Shutdown 流程
- JVM 接受 SIGTERM 信號(hào)棵帽,開始關(guān)閉 Spring Container
- Spring EventListener 監(jiān)聽 ContextClosedEvent 事件,關(guān)閉開始后回調(diào)
- EventListener 更新 Spring Boot HealthIndicator 為 "OUT_OF_SERVICE"
- 使用 Thread.sleep 延遲 Context 關(guān)閉,以便負(fù)載均衡器查看更新的 HealthIndicator 狀態(tài),并停止向此實(shí)例轉(zhuǎn)發(fā)請求
- 當(dāng) Thread.sleep 結(jié)束, Tomcat container 正常關(guān)閉屉栓。首先通過暫停 Connector沼溜,不再接受新的請求,然后通過配置的時(shí)間讓 Tomcat 線程池處理活躍的線程
- 最后, Spring Context 關(guān)閉
? Github Demo URL
示例中客税,Spring Boot 配置如下:
graceful.shutdown.enabled=true
graceful.shutdown.timeout=60s
graceful.shutdown.wait=30s
正常運(yùn)行時(shí),執(zhí)行 curl http://127.0.0.1:8080/actuator/health
撕贞,結(jié)果如下:
{
"status": "UP"
}
關(guān)閉服務(wù)后更耻,30 秒內(nèi),執(zhí)行 curl http://127.0.0.1:8080/actuator/health
捏膨,結(jié)果如下:
{
"status": "OUT_OF_SERVICE"
}
30 秒內(nèi)秧均,服務(wù)能正常接收新的請求。30 秒后号涯,服務(wù)不再接受新的請求目胡,會(huì)有如下幾種情況:
- Tomcat 無請求待處理,服務(wù)立即關(guān)閉
- Tomcat 有請求待處理链快,處理時(shí)間在 60 秒內(nèi)誉己,服務(wù)會(huì)在所有請求處理完后立即關(guān)閉
- Tomcat 有請求待處理,處理時(shí)間超過 60 秒域蜗,服務(wù)會(huì)在 60 秒后強(qiáng)制關(guān)閉巨双,異常退出