SpringBoot3實現(xiàn)優(yōu)雅停機的完整流程
在現(xiàn)代微服務架構中,優(yōu)雅停機(Graceful Shutdown)是一項重要功能,可以確保服務在關閉時處理完所有當前請求,避免突然終止連接或丟失數(shù)據(jù)。Spring Boot 3 提供了對優(yōu)雅停機的內(nèi)置支持,允許在關閉應用程序上下文期間為現(xiàn)有請求設置一個寬限期,同時防止新請求進入。本文將詳細介紹 Spring Boot 3 的優(yōu)雅停機機制,重點分析 Tomcat 和 Reactor Netty 兩種常用的嵌入式 Web 服務器的優(yōu)雅停機流程。
1. 什么是優(yōu)雅停機?
優(yōu)雅停機的目標是在服務關閉時:
- 允許當前的處理請求在指定的寬限期內(nèi)完成。
- 阻止新的請求進入。
- 向外部監(jiān)控或負載均衡器標記服務為不可用。
這種機制可以確保服務在維護或版本升級時避免數(shù)據(jù)丟失和請求中斷,提供更高的穩(wěn)定性和可用性。
2. Spring Boot 3 優(yōu)雅停機的配置
在 Spring Boot 3 中,我們可以使用 server.shutdown 配置來開啟優(yōu)雅停機,并指定寬限期。配置項如下:
server:
shutdown: "graceful" # 開啟優(yōu)雅停機
spring:
lifecycle:
timeout-per-shutdown-phase: "20s" # 停機的寬限期,默認為 30 秒
此配置項適用于所有四種嵌入式 Web 服務器:Tomcat、Jetty、Reactor Netty 和 Undertow。
注意:Spring Boot 3 默認禁用優(yōu)雅停機,需要將
server.shutdown設置為graceful以啟用。
3. Tomcat 和 Reactor Netty 的優(yōu)雅停機機制
Spring Boot 3 支持在不同的 Web 服務器上實現(xiàn)優(yōu)雅停機。以下是 Tomcat 和 Reactor Netty 的具體停機方式:
3.1 Tomcat 優(yōu)雅停機
使用Tomcat的優(yōu)雅關機需要Tomcat 9.0.33或更高版本,在 Tomcat 上啟用優(yōu)雅停機后,當收到關閉信號時,它將停止接受新的連接請求,并在網(wǎng)絡層阻止傳入流量:
- 阻止新請求:一旦啟動關閉流程,Tomcat 將在網(wǎng)絡層拒絕新的請求連接。
- 完成現(xiàn)有請求:Tomcat 會確保已有請求在指定的寬限期內(nèi)完成。如果請求未完成且寬限期到達,將強制終止。
注意:若某些請求未在寬限期內(nèi)完成,則這些請求將被中斷。
3.2 Reactor Netty 優(yōu)雅停機
Reactor Netty 是 Spring WebFlux 默認使用的非阻塞式 Web 服務器,適合響應式編程。Reactor Netty 的優(yōu)雅停機實現(xiàn)方式如下:
- 網(wǎng)絡層停止:當關閉信號到達,Reactor Netty 將停止接受新請求連接,并釋放相關資源。
- 等待寬限期:當前所有活動請求在寬限期內(nèi)繼續(xù)處理;在寬限期結束后,未完成的請求將被強制中止。
Reactor Netty 在優(yōu)雅停機期間通過停止接受新的連接來實現(xiàn)無縫停機。其無阻塞模型讓服務在短時間內(nèi)完成停機。
Reactor Netty 在優(yōu)雅停機期間通過停止接受新的連接來實現(xiàn)無縫停機。其無阻塞模型讓服務在短時間內(nèi)完成停機。
4. 優(yōu)雅停機的流程
在 Tomcat 和 Reactor Netty 上的優(yōu)雅停機流程類似,大致包含以下幾個步驟:
- 標記服務不可用:停止接收新的請求,通常是通過在負載均衡器中剔除該服務或在網(wǎng)絡層阻斷連接來實現(xiàn)。
- 設置寬限期:當前請求允許在寬限期內(nèi)繼續(xù)處理。
- 關閉活動連接:寬限期結束后,所有未完成的請求會被中止,資源釋放。
Spring Boot 3 的 SmartLifecycle 和 ApplicationContext 控制器在關閉階段對生命周期進行管理,保證所有組件按照順序優(yōu)雅停止。
5. 實現(xiàn)優(yōu)雅停機的完整示例
我們可以創(chuàng)建一個簡單的 Spring Boot 3 應用來展示優(yōu)雅停機配置。
5.1 代碼示例
在 application.yml 中啟用優(yōu)雅停機并設置寬限期為 30 秒:
server:
shutdown: "graceful" # 開啟優(yōu)雅停機
spring:
lifecycle:
timeout-per-shutdown-phase: "30s" # 停機的寬限期,默認為 30 秒
創(chuàng)建一個簡單的 REST 控制器,模擬一個處理時間較長的請求:
@RestController
@RequestMapping("/api")
public class DemoController {
@GetMapping("/long-running")
public String longRunningTask() throws InterruptedException {
System.out.println("開始執(zhí)行耗時任務...");
Thread.sleep(20000); // 模擬耗時任務
return "任務完成";
}
}
此控制器會等待 20 秒后返回結果。通過優(yōu)雅停機機制,即使應用關閉,也會允許該任務在 30 秒寬限期內(nèi)完成。
啟動類里添加一段代碼方便打印服務何時停止運行:
@PreDestroy
public void destroy() {
System.out.println("Application is destroyed");
}
5.2 IDEA 停止服務
由于 IDEA 運行的服務點擊紅點結束,會直接停止程序,無法模擬停機,Linux 上通過 java -jar 運行的程序沒有這種煩惱,所有此處引入 actuator 的功能,它可以執(zhí)行 shutdown。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
增加如下 actuator 配置:
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
shutdown:
enabled: true # 開放停機端口
調(diào)用 curl -X POST http://localhost:8080/actuator/shutdown,即可停止服務:

5.3 測試優(yōu)雅停機
啟動應用并訪問 http://localhost:8080/api/long-running,然后調(diào)用 http://localhost:8080/actuator/shutdown 停止服務。
請求在寬限期內(nèi)返回 任務完成。

修改超期時間為 10s,超過寬限期后,請求被中止。

6. 負載均衡器中的停機策略
在實際應用中,負載均衡器(如 Nginx、Kubernetes)也可以在服務停機時配合優(yōu)雅停機流程,通過從負載均衡池中剔除當前實例來防止新流量進入。這樣可以確保所有請求被其他實例接管,而當前實例只處理已有請求,直至完成后停機。
7. 優(yōu)雅停機的注意事項
- 寬限期配置:設置合理的寬限期,確保長時間請求可以完成。
- 負載均衡器協(xié)作:在生產(chǎn)環(huán)境中建議與負載均衡器配合,實現(xiàn)完整的優(yōu)雅停機流程。
- 避免頻繁停機:頻繁停機會中斷長時間任務,應避免在高負載時頻繁重啟應用。
8. 總結
在 Spring Boot 3 中,通過簡單配置即可實現(xiàn)優(yōu)雅停機,確保服務在關閉時能夠完整處理當前請求,減少對用戶體驗的影響。在 Tomcat 和 Reactor Netty 上實現(xiàn)的優(yōu)雅停機過程相似,都采用了在網(wǎng)絡層阻止新請求和在應用層設置寬限期的方式。優(yōu)雅停機機制在高并發(fā)服務中顯得尤為重要,是微服務架構中保持穩(wěn)定性和一致性的關鍵。
以上就是SpringBoot3實現(xiàn)優(yōu)雅停機的完整流程的詳細內(nèi)容,更多關于SpringBoot3優(yōu)雅停機的資料請關注腳本之家其它相關文章!
相關文章
Java創(chuàng)建多線程異步執(zhí)行實現(xiàn)代碼解析
這篇文章主要介紹了Java創(chuàng)建多線程異步執(zhí)行實現(xiàn)代碼解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-07-07
解析springboot集成AOP實現(xiàn)日志輸出的方法
如果這需要在每一個controller層去寫的話代碼過于重復,于是就使用AOP定義切面 對其接口調(diào)用前后進行攔截日志輸出。接下來通過本文給大家介紹springboot集成AOP實現(xiàn)日志輸出,需要的朋友可以參考下2021-11-11
SpringBoot配置文件properties和yml的實現(xiàn)
本文主要介紹了SpringBoot配置文件properties和yml的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-04-04
如何解決java:找不到符號符號:類__(使用了lombok的注解)
在使用IntelliJ IDEA開發(fā)Java項目時,可能遇到通過@lombok注解自動生成get和set方法不生效的問題,解決這一問題需要幾個步驟,首先,確認Lombok插件已在IDEA中安裝并啟用,其次,確保項目中已添加Lombok的依賴,對于Maven和Gradle項目2024-10-10

