【SpringBoot实战】优雅关闭服务

文章目录

一、什么是优雅关闭?

优雅关闭(Graceful Shutdown) 是指服务在关闭或重启时,先完成所有正在处理的请求,再安全终止进程的机制。这种机制能有效避免以下问题:

  • 用户请求突然中断导致的客户端报错
  • 数据库事务执行到一半被强制终止
  • 负载均衡将流量导向正在关闭的节点

下面来看典型的架构场景:

当对服务实例进行滚动更新时,若直接终止实例,正在处理的请求将失败。

二、优雅关闭的核心步骤

  1. 流量摘除
    CI/CD系统将目标节点从负载均衡(如Nginx)的后端服务器组中移除
  2. 接收终止信号
    进程接收到操作系统发送的终止信号(如SIGTERM)
  3. 停止接收新请求
    服务立即关闭端口监听,拒绝新请求进入
  4. 等待既有请求完成
    服务等待所有正在处理的请求完成(包括长任务)
  5. 进程安全退出
    资源清理后终止进程

三、SpringBoot优雅关闭实现

自 SpringBoot 2.3.0 起官方内置优雅关闭支持:
点击访问

翻译过来这句话的意思就是:

将 Web 服务的优雅关闭集成到应用程序上下文(ApplicationContext)的生命周期处理中

配置方式(application.yml)

yaml 复制代码
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 实现:

java 复制代码
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
    // 1. 关闭ServerSocket停止接收请求
    // 2. 检查活动请求计数器
    // 3. 等待计数器归零或超时
}));

六、总结

通过 SpringBoot 原生支持的优雅关闭机制,配合基础设施的流量控制,可实现服务的零中断发布。关键点在于:

  1. 正确配置 server.shutdown=graceful + 超时时间
  2. 使用 SIGTERM 而非 SIGKILL 终止进程
  3. 基础设施层保证流量摘除先于进程终止

生产环境发布效果对比:

未启用优雅关闭:发布期间错误率飙升

启用后:错误率曲线保持平稳 🚀

相关推荐
计算机毕设定制辅导-无忧学长1 分钟前
《基于微信小程序的个人智能刷题助手的设计与实现》
java·spring boot·mysql·微信小程序·uniapp·个人智能刷题助手系统
武子康6 分钟前
把调用移进同一个类之后:一次 Spring 事务回滚反例
人工智能·后端·agent
步行cgn15 分钟前
Spring MVC 中实现 request 域效果的几种方式
java·后端
Thomas.Sir18 分钟前
第3课:SpringBoot4.x 自动配置原理:@EnableAutoConfiguration底层源码剖析
java·spring boot
Rain的Java大神之路22 分钟前
MySQL 被高并发打爆?从定位到分库分表逐层拆解(含秒杀库存实战)
java·后端·面试
cc_瀚海知行25 分钟前
工具调用 6|助手什么时候该停下来?
java·服务器·前端·人工智能·python·ai
Cosolar27 分钟前
DeepInfer 完全教程:DeepSeek 内部推理框架原理、架构与部署实战
后端·架构·github
YDS82927 分钟前
Small Spring IOC篇:应用上下文实现和Bean的扩展
java·后端·spring
Pniubi30 分钟前
ConcurrentHashMap拆分线程池难点再讲
java·jvm
golang学习记30 分钟前
IDEA 的 Java 智能,现在跑到 Cursor 和 VS Code 里去了
java·ide·vscode·intellij-idea·claude code