当前位置: 首页 > news >正文

Spring Boot优雅关闭全解析

以下这段文字来自 Spring Boot 官方文档(5.8 节“Graceful shutdown”),讲的是 如何在 Spring Boot 应用中启用“优雅关闭”(Graceful Shutdown)功能。下面我们逐段解析,并用通俗易懂的方式解释其含义和应用场景。


🌟 什么是“优雅关闭”?

想象一下:你的 Web 服务正在处理用户请求,比如用户正在下单、上传文件、查询数据。这时,你决定关闭服务(比如部署新版本)。如果直接“粗暴”地关掉服务,那些正在进行的请求就会被中断,导致数据不一致、用户体验差等问题。

优雅关闭 就是:在关闭服务时,先“告诉”服务器:“不要再接收新请求了,但已经进来的请求请让我处理完,等它们都完成了,再真正关闭。”

这样可以避免请求丢失或中途失败,提升系统的稳定性和用户体验。


🔍 原文逐句解读

1.

Graceful shutdown is supported with all four embedded web servers (Jetty, Reactor Netty, Tomcat, and Undertow) and with both reactive and Servlet-based web applications.

✅ 含义:

  • Spring Boot 支持四种内嵌 Web 服务器:Jetty、Reactor Netty、Tomcat、Undertow
  • 无论是基于 响应式编程(如 WebFlux)还是传统的 Servlet 模型(如 Spring MVC),都支持优雅关闭。

👉 也就是说:无论你用哪种技术栈,都能使用这个功能。


2.

It occurs as part of closing the application context and is performed in the earliest phase of stopping SmartLifecycle beans.

✅ 含义:

  • 优雅关闭是 Spring 应用上下文(ApplicationContext)关闭过程的一部分。
  • 它发生在 SmartLifecycle 组件停止的最早阶段

📌 补充知识:

  • SmartLifecycle 是 Spring 提供的一个接口,用于控制 Bean 的启动和停止顺序。
  • 把优雅关闭放在“最早阶段”意味着:一旦开始关,就立刻进入“拒绝新请求”的状态,防止新的请求进来干扰关闭流程。

3.

This stop processing uses a timeout which provides a grace period during which existing requests will be allowed to complete but no new requests will be permitted.

✅ 含义:

  • 有一个 超时时间(timeout),叫做“宽限期”(grace period)。
  • 在这段时间内:
    • ✅ 已经到达的请求:允许继续执行,直到完成。
    • ❌ 新的请求:不允许再进来。

📌 举例:
如果你设置 timeout = 30s,那么系统最多会等 30 秒来让正在进行的请求完成。超过 30 秒还没完成的请求,会被强制终止。


4.

The exact way in which new requests are not permitted varies depending on the web server that is being used. Jetty, Reactor Netty, and Tomcat will stop accepting requests at the network layer. Undertow will accept requests but respond immediately with a service unavailable (503) response.

✅ 含义:不同服务器处理“拒绝新请求”的方式不一样:

服务器如何拒绝新请求
Jetty / Reactor Netty / Tomcat直接在网络层拒绝连接,客户端会收到连接失败(如 Connection refused)
Undertow仍然接受连接,但立即返回 HTTP 状态码 503 Service Unavailable

📌 区别:

  • 前三者更“强硬”:直接不让连接进来。
  • Undertow 更“友好”:告诉客户端“我现在忙,不能服务你”,适合某些负载均衡场景。

5.

Graceful shutdown with Tomcat requires Tomcat 9.0.33 or later.

✅ 含义:

  • 如果你用的是 Tomcat,必须使用 9.0.33 或更高版本 才支持优雅关闭。
  • 老版本不支持,即使配置了也不会生效。

⚠️ 注意:Spring Boot 2.3+ 才引入此功能,且默认内嵌的 Tomcat 版本需满足要求。


6.

To enable graceful shutdown, configure the server.shutdown property, as shown in the following example:

server.shutdown=graceful

✅ 含义:
这是开启优雅关闭的关键配置!

application.ymlapplication.properties 中添加:

# application.yml
server:shutdown: graceful

# application.properties
server.shutdown=graceful

👉 默认值是 immediate(立即关闭),设为 graceful 才启用优雅关闭。


7.

To configure the timeout period, configure the spring.lifecycle.timeout-per-shutdown-phase property, as shown in the following example:

spring.lifecycle.timeout-per-shutdown-phase=20s

✅ 含义:
设置“宽限期”——即最多等多久让现有请求完成。

例如:

spring:lifecycle:timeout-per-shutdown-phase: 30s

表示:最多等待 30 秒。

⚠️ 注意:

  • 如果某个请求跑了 40 秒还没完,那它会在 30 秒时被强制中断。
  • 这个超时是全局的,适用于所有需要优雅停止的组件。

8.

Using graceful shutdown with your IDE may not work properly if it does not send a proper SIGTERM signal. Refer to the documentation of your IDE for more details.

✅ 含义:

  • 优雅关闭依赖操作系统发送的 SIGTERM 信号(Linux/Unix 下的标准终止信号)。
  • 但很多 IDE(如 IntelliJ IDEA、Eclipse) 在点击“停止按钮”时,并不会发送 SIGTERM,而是直接杀进程(相当于 kill -9),这就跳过了优雅关闭流程!

👉 结果:配置了也没用,请求照样被中断。

✅ 解决方案:

  • 在生产环境使用命令行启动(如 java -jar app.jar),并通过 kill <pid> 发送 SIGTERM。
  • 或者使用容器化部署(如 Docker),配合 stop-signal: SIGTERM 和合理的 stopTimeout

✅ 总结:如何正确使用优雅关闭?

第一步:修改配置文件
# application.yml
server:shutdown: graceful    # 开启优雅关闭spring:lifecycle:timeout-per-shutdown-phase: 30s   # 最多等待30秒
第二步:确保环境支持
  • 使用 Tomcat ≥ 9.0.33(Spring Boot 2.3+ 默认满足)
  • 部署方式要能发送 SIGTERM 信号(避免 kill -9 或 IDE 强制停止)
第三步:测试验证

你可以通过以下方式测试:

  1. 启动应用
  2. 发起一个长请求(比如 sleep 10 秒的接口)
  3. 在请求执行过程中,执行 kill <pid>(而不是 kill -9
  4. 观察日志:是否等待请求完成后才关闭?

💡 适用场景

场景是否推荐使用优雅关闭
生产环境部署/滚动更新✅ 强烈推荐
使用 Kubernetes / Docker✅ 推荐,配合合理的 terminationGracePeriodSeconds
本地开发调试⚠️ 可能无效(IDE 不发 SIGTERM)
高并发交易系统✅ 必须使用,防止订单丢失

📌 小贴士

  • 优雅关闭 ≠ 永远不中断请求,它只是给了一个“缓冲期”。
  • 超时后仍未完成的请求,仍会被中断。
  • 建议结合监控和日志,观察关闭期间的请求情况。

如有需要,我可以提供一个 Spring Boot 示例项目Docker + Kubernetes 配置示例 来演示优雅关闭的实际效果。是否需要?

http://www.dtcms.com/a/511790.html

相关文章:

  • 授权登录网站怎么做网站源码怎么做
  • 网站建设遇到哪些攻击网站开发外贸客户
  • 未来之窗昭和仙君(二十六)通用押金系统开发——东方仙盟筑基期
  • 【案例】Unity 平台访问文件浏览器(汇总)
  • Matlab 曲线拟合
  • 基于CSMA-CA协议的V2X通信MATLAB仿真
  • 基于matlab实现的DnCNN网络
  • 网站一般用什么工具做wordpress英文版切换中文
  • 十大最佳摄影网站windows 版 wordpress
  • ruby 、gem 和 cocoapods的联系与区别
  • Python 圆台体积和表面积计算程序(Program for Volume and Surface area of Frustum of Cone)
  • MySQL索引指南
  • 分销网站制作条件免费机械网站模板
  • day01 pyspark入门和基础环境
  • 公司网站 URL 地址规范
  • 建设一个广告联盟的网站免费祝福网页在线制作
  • 实现Trie(前缀树)
  • 杰理SDK入门教程(六):自定义按键事件
  • gray = roi.clone();和gray = roi;的区别是什么?
  • STM32中MX_TIM2_Init函数和HAL_TIM_Base_MspInit函数区别
  • 【基于Selenium的智能滑块验证码破解技术详解】
  • AI体测设备服务商
  • 网站之间如何做视频交换惠州搜索引擎优化
  • 李宏毅机器学习笔记28
  • 【开题答辩实录分享】以《智慧社区信息化服务平台》为例进行答辩实录分享
  • 京东网站建设过程东莞建设网站的位置
  • SAP SD销售订单执行跟踪报表分享
  • 数据挖掘比赛baseline参考
  • [人工智能-大模型-19]:GitHub Copilot:程序员的 AI 编程副驾驶
  • 【JVM】低延迟垃圾收集器:Shenandoah收集器与ZGC收集器