最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot 優(yōu)雅停機實現(xiàn)原理與最佳實踐指南

 更新時間:2026年04月20日 09:32:09   作者:程序員1970  
文章介紹了Spring Boot在2.3版本中引入的優(yōu)雅停機機制,詳細解釋了優(yōu)雅停機的概念、核心組件與層級關(guān)系、Spring Boot 2.3前后的區(qū)別,以及在生產(chǎn)環(huán)境中的最佳實踐,強調(diào)了啟用優(yōu)雅停機的重要性,以提高系統(tǒng)的高可用性和穩(wěn)定性

微服務(wù)和云原生時代,應(yīng)用的平滑啟停是保障系統(tǒng)高可用的關(guān)鍵環(huán)節(jié)。Spring Boot 在 2.3 版本引入了對內(nèi)嵌 Web 容器優(yōu)雅停機的原生支持,改變此前需要手動編碼實現(xiàn)局面。

一、什么是“優(yōu)雅停機”?

優(yōu)雅停機(Graceful Shutdown) 是指在應(yīng)用停止過程中:

  1. 立即停止接收新請求;
  2. 允許已進入的請求繼續(xù)處理完成;
  3. 安全釋放資源(數(shù)據(jù)庫連接、線程池、緩存等);
  4. 避免客戶端收到 5xx 錯誤或連接中斷。

若未實現(xiàn)優(yōu)雅停機,在滾動更新、縮容或重啟時,極易出現(xiàn)如下典型異常:

ERROR ... - Error creating bean with name 'orderController': 
Singleton bean creation not allowed while singletons of this factory are in destruction
org.springframework.beans.factory.BeanCreationNotAllowedException: ...

異常表明:Spring 容器正在銷毀,但仍有請求試圖獲取 Controller Bean —— 這正是停機流程設(shè)計不當?shù)闹苯芋w現(xiàn)。

二、核心組件與層級關(guān)系

要理解停機流程,需先厘清以下組件的包含關(guān)系:

JVM
 └── 內(nèi)嵌 Web 容器(如 Tomcat)
      └── Servlet 容器(StandardContext)
           └── DispatcherServlet(Spring MVC 入口)
                └── Spring ApplicationContext(IoC 容器)
                     └── 所有 Spring Bean(@Controller, @Service 等)
  • Web 容器(Tomcat/Jetty/Undertow):負責(zé)網(wǎng)絡(luò)連接與線程調(diào)度。
  • Servlet 容器:管理 Servlet、Filter 生命周期。
  • Spring 容器:即 ApplicationContext,管理 Bean 的創(chuàng)建與銷毀。
  • Spring Boot不是容器,而是自動集成 Web 容器 + Spring 容器的啟動框架。

?? 關(guān)鍵點:Spring 容器運行在 Web 容器內(nèi)部。停機時,必須協(xié)調(diào)二者關(guān)閉順序,否則就會出現(xiàn)“Web 容器還在處理請求,但 Spring 容器已拒絕服務(wù)”的競態(tài)條件。

三、Spring Boot < 2.3:手動實現(xiàn)的“偽優(yōu)雅”

在2.3之前,Spring Boot 沒有內(nèi)置優(yōu)雅停機能力。默認行為是:

  1. 收到 SIGTERM(如 kill -15);
  2. 立即關(guān)閉 Spring 容器 → 設(shè)置 singletonsCurrentlyInDestruction = true;
  3. Web 容器仍在運行,繼續(xù) accept 新連接并分配線程;
  4. 若此時有請求進入,DispatcherServlet 嘗試通過 getBean("orderController") 獲取 Controller;
  5. 因 Spring 容器已標記為“銷毀中”,拋出 BeanCreationNotAllowedException

? 問題本質(zhì):關(guān)閉順序錯誤

先關(guān) Spring,再關(guān) Web 容器 → 存在危險時間窗口。

??? 開發(fā)者workaround

需手動實現(xiàn)以下邏輯:

@Component
public class GracefulShutdown implements TomcatConnectorCustomizer, 
                                      ApplicationListener<ContextClosedEvent> {
    private volatile Connector connector;
    @Override
    public void customize(Connector connector) {
        this.connector = connector;
    }
    @Override
    public void onApplicationEvent(ContextClosedEvent event) {
        connector.pause(); // 停止接收新請求
        Executor executor = connector.getProtocolHandler().getExecutor();
        if (executor instanceof ThreadPoolExecutor) {
            try {
                ((ThreadPoolExecutor) executor).shutdown();
                ((ThreadPoolExecutor) executor).awaitTermination(30, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

同時需注冊到 Tomcat:

@Bean
public ServletWebServerFactory servletContainer() {
    TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
    tomcat.addConnectorCustomizers(gracefulShutdown());
    return tomcat;
}

?? 即便如此,仍無法完美處理 HTTP/1.1 keep-alive 連接復(fù)用帶來的新請求。

四、Spring Boot ≥ 2.3:原生優(yōu)雅停機

Spring Boot 2.3 引入了 標準化的優(yōu)雅停機機制,通過兩行配置即可啟用:

server:
  shutdown: graceful          # 啟用優(yōu)雅停機
spring:
  lifecycle:
    timeout-per-shutdown-phase: 30s  # 等待超時時間

? 核心思想:反轉(zhuǎn)關(guān)閉順序 + 流量控制前置

停機流程變?yōu)椋?/p>

  1. Web 容器立即 pause:停止 accept 新連接(Tomcat 調(diào)用 connector.pause());
  2. 等待已進入的請求完成:最多等待 timeout-per-shutdown-phase 時間;
  3. 確認無活躍請求后,關(guān)閉 Spring 容器:銷毀所有 Bean;
  4. 徹底停止 Web 容器線程池。

?? 底層原理

1.SmartLifecycle控制關(guān)閉階段

Spring Boot 注冊了 WebServerGracefulShutdownLifecycle,它實現(xiàn) SmartLifecycle 接口,并設(shè)置:

@Override
public int getPhase() {
    return Integer.MAX_VALUE; // 最后啟動,最先停止
}

確保其 stop() 方法在普通 Bean 銷毀之前執(zhí)行。

2.WebServer 接口標準化

不同內(nèi)嵌服務(wù)器實現(xiàn)統(tǒng)一的 GracefulShutdown 行為:

  • Tomcatpause() + 等待線程池
  • Jetty:停止 acceptor 線程
  • Undertow:返回 503 給新請求
  • Reactor Netty:發(fā)送 GOAWAY(HTTP/2)

3.與 Spring 生命周期深度集成

通過 LifecycleProcessor 協(xié)調(diào)所有 SmartLifecycle Bean 的關(guān)閉順序,確保 Web 容器優(yōu)雅關(guān)閉完成之后,才觸發(fā) ApplicationContext.close()。

五、2.3 前后對比總表

維度Spring Boot < 2.3Spring Boot ≥ 2.3
是否內(nèi)置支持? 需手動編碼? 開箱即用
關(guān)閉起點Spring 容器Web 容器
新請求處理繼續(xù) accept → 高風(fēng)險立即拒絕(pause/503)→ 安全
已進入請求可能因 Spring 關(guān)閉而失敗等待完成(最多 timeout)
典型異常BeanCreationNotAllowedException 高頻極少(除非超時)
配置復(fù)雜度高(需自定義監(jiān)聽器)低(僅需 YAML)
多容器支持僅限手動適配自動支持 Tomcat/Jetty/Undertow/Netty
K8s 友好度優(yōu)秀

六、生產(chǎn)環(huán)境最佳實踐

1.啟用優(yōu)雅停機(2.3+)

server:
  shutdown: graceful
spring:
  lifecycle:
    timeout-per-shutdown-phase: 45s  # > 業(yè)務(wù)最大請求耗時

2.Kubernetes 部署配合 preStop

spec:
  containers:
    - name: app
      lifecycle:
        preStop:
          exec:
            command: ["sleep", "15"]  # 給 LB 時間摘除節(jié)點
      terminationGracePeriodSeconds: 60

3.Windows 服務(wù)需走 Actuator

management:
  endpoint:
    shutdown:
      enabled: true
  endpoints:
    web:
      exposure:
        include: "shutdown"

并通過外部命令觸發(fā):

curl -X POST http://localhost:8080/actuator/shutdown

4.監(jiān)控與告警

  • 監(jiān)控停機期間的 5xx 錯誤率;
  • 若仍有 BeanCreationNotAllowedException,檢查:
    • 超時時間是否足夠;
    • LB 摘除延遲;
    • 是否存在長輪詢/WebSocket 未處理。

?? 一句話建議:
只要你的Spring Boot 版本 ≥ 2.3,務(wù)必啟用 server.shutdown=graceful,并配合基礎(chǔ)設(shè)施實現(xiàn)流量摘除。這能顯著提升系統(tǒng)在滾動更新、彈性伸縮場景下的穩(wěn)定性與用戶體驗。

到此這篇關(guān)于SpringBoot 優(yōu)雅停機實現(xiàn)原理與最佳實踐指南的文章就介紹到這了,更多相關(guān)SpringBoot 優(yōu)雅停機內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java根據(jù)擴展名獲取系統(tǒng)圖標和文件圖標示例

    java根據(jù)擴展名獲取系統(tǒng)圖標和文件圖標示例

    這篇文章主要介紹了java根據(jù)擴展名獲取系統(tǒng)圖標和文件圖標示例,需要的朋友可以參考下
    2014-03-03
  • IDEA使用Maven創(chuàng)建module出現(xiàn)Ignored?pom.xml問題及解決

    IDEA使用Maven創(chuàng)建module出現(xiàn)Ignored?pom.xml問題及解決

    這篇文章主要介紹了IDEA使用Maven創(chuàng)建module出現(xiàn)Ignored?pom.xml問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Java線程CPU飆高、僵尸進程和磁盤滿的排查技巧

    Java線程CPU飆高、僵尸進程和磁盤滿的排查技巧

    線上故障就像埋在系統(tǒng)里的定時炸彈——CPU突然飆高導(dǎo)致服務(wù)卡頓、海量日志找不到異常、磁盤滿了直接宕機,每一種都能讓程序員頭皮發(fā)麻,所以今天整理了4類高頻線上故障的排查套路,附實操命令,需要的朋友可以參考下
    2026-02-02
  • SpringBoot2使用Jetty容器操作(替換默認Tomcat)

    SpringBoot2使用Jetty容器操作(替換默認Tomcat)

    這篇文章主要介紹了SpringBoot2使用Jetty容器操作(替換默認Tomcat),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • springboot的war和jar包的使用詳解

    springboot的war和jar包的使用詳解

    這篇文章主要介紹了springboot的war和jar包的使用詳解,非常不錯,具有一定的參考借鑒價值 ,需要的朋友可以參考下
    2018-11-11
  • 史上最佳springboot Locale 國際化方案

    史上最佳springboot Locale 國際化方案

    今天給大家分享史上最佳springboot Locale 國際化方案,本文通過實例圖文相結(jié)合給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-08-08
  • Java 泛型總結(jié)及詳解

    Java 泛型總結(jié)及詳解

    這篇文章主要介紹了Java 泛型的相關(guān)資料,并附簡單實例代碼,需要的朋友可以參考下
    2016-09-09
  • 關(guān)于java方法區(qū)詳解

    關(guān)于java方法區(qū)詳解

    這篇文章主要介紹了關(guān)于java方法區(qū)的使用解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • SpringBoot項目如何打包成war包

    SpringBoot項目如何打包成war包

    使用SpringBoot 開發(fā)項目,由于內(nèi)置了Tomcat,所以項目可以直接啟動,部署到服務(wù)器的時候,直接打成 jar 包,就可以運行了,這篇文章主要介紹了SpringBoot項目如何打包成war包,需要的朋友可以參考下
    2024-07-07
  • Spring事務(wù)捕獲異常后依舊回滾的解決

    Spring事務(wù)捕獲異常后依舊回滾的解決

    本文主要介紹了Spring事務(wù)捕獲異常后依舊回滾的解決,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01

最新評論

广水市| 遂宁市| 轮台县| 黔西县| 高陵县| 敖汉旗| 陆丰市| 长治市| 铅山县| 临沭县| 甘谷县| 朔州市| 巨鹿县| 盐城市| 濉溪县| 永新县| 定远县| 赣榆县| 长汀县| 磴口县| 靖州| 禄丰县| 博湖县| 宁陕县| 邢台县| 阆中市| 潞城市| 阿鲁科尔沁旗| 封丘县| 嵊州市| 开鲁县| 加查县| 胶南市| 博野县| 金昌市| 凤阳县| 库伦旗| 金堂县| 永州市| 平顶山市| 永嘉县|