news 2026/9/15 3:49:05

SpringBoot优雅停机,别再kill-9了

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringBoot优雅停机,别再kill-9了

线上发布时,你有没有用过kill -9强行终止应用?进程瞬间消失,部署脚本跑得飞快,看起来一切正常。但用户那边可能正在提交订单、正在支付回调、正在上传文件——这些请求在毫秒之间被腰斩,数据写了一半,消息发了一半,分布式锁没释放,数据库连接没归还。一次kill -9的代价,可能是一批用户投诉、一笔对账差账、甚至一次线上故障。

从 Spring Boot 2.3 开始,框架正式内置了优雅停机功能,覆盖 Tomcat、Jetty、Undertow 和 Reactor Netty 四种内嵌 Web 服务器。但直到今天,很多团队依然没有开启它。

开启优雅停机,只需要两行配置

application.yml中加上两个配置项即可:

text
复制
下载
server: shutdown: "graceful" spring: lifecycle: timeout-per-shutdown-phase: "20s"

第一行告诉 Spring Boot 收到关闭信号后不要立即终止,而是先停止接收新请求,再等待正在处理的请求完成。第二行设置宽限期,默认值是 30 秒,超过这个时间仍未完成的请求会被强制中断。

不同 Web 服务器的行为略有差异:Tomcat、Jetty 和 Reactor Netty 在网络层直接拒绝新连接;Undertow 则会接受新请求但立即返回 503,因为它的线程模型决定了“不接收”不如“快速拒绝”更安全。

Kubernetes 环境下,仅靠 Spring Boot 配置还不够

如果你在 K8s 中部署,有一个关键陷阱:Spring Boot 的优雅停机处理的是“已经到达 Pod 的请求”,但它无法阻止 Kubernetes 在 Pod 被摘除之前继续向它转发新流量。K8s 默认在发送 SIGTERM 信号的同时,就开始了从 Service Endpoint 中移除 Pod 的操作——但负载均衡器的状态同步存在延迟。

正确的做法是在 Deployment 中配置preStopHook,在 SIGTERM 发出前预留一段缓冲时间:

text
复制
下载
lifecycle: preStop: exec: command: ["/bin/sh", "-c", "sleep 15"]

这 15 秒的作用是:让 K8s 有足够时间将这个 Pod 从 Endpoint 中摘除,确保所有新流量已经停止转发到该实例。之后再发送 SIGTERM,Spring Boot 才开始优雅停机流程。同时,terminationGracePeriodSeconds必须大于preStop的 sleep 时间加上 Spring Boot 的宽限期,否则容器还没完成清理就会被 K8s 强制杀死。

别忘了清理你自定义的资源

Spring Boot 的优雅停机默认只负责 Web 层的请求排空。如果你在代码中自定义了线程池、调度器或消息队列监听器,这些资源需要你自己在@PreDestroy方法中关闭。

线程池的优雅关闭关键在两个参数:setWaitForTasksToCompleteOnShutdown(true)让线程池在关闭前等待队列中的任务执行完毕,setAwaitTerminationSeconds(60)设置最大等待时间。对于数据库连接池,可以在@PreDestroy中先暂停连接借出,再等待活跃连接归还。有一个容易被忽略的坑:如果你的线程池是通过new关键字自己创建的,而不是交给 Spring 容器管理,@PreDestroy不会被调用,必须手动注册销毁逻辑。

从“启动时优雅”到“关闭时优雅”

Spring Boot 优雅停机的意义,不在于它用了多复杂的技术——底层不过是 JVM 的 Shutdown Hook 机制。它的真正价值在于提醒我们:一个服务的生命周期,不应该只有“启动”和“运行”两个状态。关闭同样是一个需要认真设计的阶段,它决定了你的系统在滚动更新、弹性扩缩容、故障迁移时,是让用户无感,还是让用户买单。

下次发布时,把kill -9换成kill -15,把那两行配置加上。这不是一个需要纠结的技术选型,而是一个应该成为默认习惯的工程素养。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 3:48:03

大模型安全评估:现状、挑战与防护技术

1. 大模型安全现状与行业关注焦点最近一份由复旦大学和上海创智学院联合发布的大模型安全评估报告在业内引发广泛讨论。这份报告首次系统性地对当前国内第一梯队的六大主流大模型进行了全方位安全测试,结果既展现了技术进步,也暴露出不少亟待解决的安全隐…

作者头像 李华
网站建设 2026/9/15 3:47:06

硬链接与软链接的本质区别:inode、引用计数与生产实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 3:45:38

Java变量命名五大致命错误:从线上事故到可落地的命名规范

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 3:44:58

PixPin 3.0.8.0 截图工具功能解析与优化技巧

1. PixPin 3.0.8.0 核心功能解析PixPin作为一款新兴的全能型截图工具,在3.0.8.0版本中集成了多项实用功能。不同于传统截图软件仅提供基础截图能力,PixPin将截图、贴图、OCR文字识别、GIF录制等高频需求整合到一个轻量级工具中。1.1 智能截图系统核心截图…

作者头像 李华
网站建设 2026/9/15 3:44:20

Linux设备驱动开发:从总线模型到设备树的实战指南

1. 为什么说“写驱动之前,先看懂总线模型”我第一次接触Linux设备驱动开发时,犯过一个很典型的错误:以为驱动开发的核心是搞懂GPIO、中断、寄存器这些硬件操作。后来被一个老工程师点破:寄存器操作只是驱动开发的“手”&#xff0…

作者头像 李华
网站建设 2026/9/15 3:44:18

智能门锁安装避坑指南:锁体兼容性与供电实测红线

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华