文章目錄
- 一、什么是優雅關閉?
- 二、優雅關閉的核心步驟
- 三、SpringBoot優雅關閉實現
- 四、關鍵注意事項
- 1. 超時時間必須配置
- 2. 信號支持局限性
- 3. 特殊請求處理
- 五、底層實現原理
- 六、總結
一、什么是優雅關閉?
優雅關閉(Graceful Shutdown) 是指服務在關閉或重啟時,先完成所有正在處理的請求,再安全終止進程的機制。這種機制能有效避免以下問題:
- 用戶請求突然中斷導致的客戶端報錯
- 數據庫事務執行到一半被強制終止
- 負載均衡將流量導向正在關閉的節點
下面來看典型的架構場景:
當對服務實例進行滾動更新時,若直接終止實例,正在處理的請求將失敗。
二、優雅關閉的核心步驟
- 流量摘除
CI/CD系統將目標節點從負載均衡(如Nginx)的后端服務器組中移除 - 接收終止信號
進程接收到操作系統發送的終止信號(如SIGTERM) - 停止接收新請求
服務立即關閉端口監聽,拒絕新請求進入 - 等待既有請求完成
服務等待所有正在處理的請求完成(包括長任務) - 進程安全退出
資源清理后終止進程
三、SpringBoot優雅關閉實現
自 SpringBoot 2.3.0 起官方內置優雅關閉支持:
點擊訪問
翻譯過來這句話的意思就是:
將 Web 服務的優雅關閉集成到應用程序上下文(ApplicationContext)的生命周期處理中
配置方式(application.yml)
server:shutdown: graceful # 啟用優雅關閉(支持Tomcat/Jetty/Undertow等Web容器)spring:lifecycle:timeout-per-shutdown-phase: 60s # 最大等待時間(超時后強制關閉),生產環境必須設置!
四、關鍵注意事項
1. 超時時間必須配置
- 為什么需要超時?
防止因某些請求阻塞(如慢SQL、死循環)導致實例永遠無法關閉 - 推薦設置
根據業務最長處理時間設定(通常 ≥ 最大請求超時時間 × 2)
2. 信號支持局限性
信號名稱 | 是否觸發優雅關閉 | 說明 |
---|---|---|
SIGTERM | ? | kill -15(默認推薦) |
SIGINT | ? | Ctrl+C 或 kill -2 |
SIGKILL | ? | kill -9 立即強制終止 |
📌 生產環境應使用 SIGTERM 觸發關閉
3. 特殊請求處理
- 長輪詢/WebSocket連接:需要業務層實現連接關閉通知
- 批處理任務:建議拆分可中斷任務,或記錄任務狀態
五、底層實現原理
SpringBoot 通過注冊 Shutdown Hook 實現:
Runtime.getRuntime().addShutdownHook(new Thread(() -> {// 1. 關閉ServerSocket停止接收請求// 2. 檢查活動請求計數器// 3. 等待計數器歸零或超時
}));
六、總結
通過 SpringBoot 原生支持的優雅關閉機制,配合基礎設施的流量控制,可實現服務的零中斷發布。關鍵點在于:
- 正確配置 server.shutdown=graceful + 超時時間
- 使用 SIGTERM 而非 SIGKILL 終止進程
- 基礎設施層保證流量摘除先于進程終止
生產環境發布效果對比:
未啟用優雅關閉:發布期間錯誤率飆升
啟用后:錯誤率曲線保持平穩 🚀