spring boot 优雅停机的核心目标是保障正在处理的请求不被中断,通过“先拒新、再等旧、最后收资源”顺序维护业务逻辑与数据一致性;2.3+版本需配置server.shutdown=graceful和spring.lifecycle.timeout-per-shutdown-phase,配合sigterm信号、合理线程池设置及@predestroy等清理机制实现完整停机流程。

Spring Boot 优雅停机的核心目标,就是不让正在处理的请求被突然中断——它通过“先拒新、再等旧、最后收资源”的顺序,保护未完成的业务逻辑和数据一致性。
配置启用内置优雅停机
Spring Boot 2.3+ 原生支持,只需两行配置:
- server.shutdown=graceful:通知内嵌 Web 容器(Tomcat/Jetty/Undertow/Reactor Netty)停止接受新连接,并标记现有连接为“不再 keep-alive”
- spring.lifecycle.timeout-per-shutdown-phase=30s(建议按实际最长请求时间设为 45s 或 60s):定义整个优雅关闭阶段的最大等待窗口;超时后强制终止,避免无限挂起
配置生效后,收到 SIGTERM(如 kill 12345)时,Web 服务器会立即拒绝新请求,同时继续服务已建立连接中的活跃请求。
确保请求真正“等完”而非“假等”
仅靠配置还不够——某些场景下(尤其是 WebFlux + Reactor Netty),默认行为可能不阻塞等待异步任务完成。关键点在于:
- Servlet 应用(Tomcat 等)通常能自动等待 Servlet 线程池中任务结束
- WebFlux 应用需额外干预:Netty 的
disposeLater().subscribe()是非阻塞的,必须显式调用block()确保 LoopResources 彻底释放 - 自定义线程池(如
@Async使用的ThreadPoolTaskExecutor)需手动配置setWaitForTasksToCompleteOnShutdown(true)和setAwaitTerminationSeconds(30)
补充清理逻辑,覆盖关键资源
优雅停机不只是等请求,还要保障事务、连接、缓存等不出问题:
- 使用
@PreDestroy或实现DisposableBean清理 Bean 级资源(如关闭手动管理的数据库连接、取消定时任务) - 监听
ContextClosedEvent执行全局收尾(例如刷新本地缓存、提交延迟日志、通知下游服务下线) - 对消息队列消费者(如 Kafka Listener)、WebSocket 会话等,应设置合理超时并主动触发 graceful shutdown 流程
触发方式要合规,避免绕过机制
只有可捕获的信号才能触发优雅流程:
- ✅ 推荐:
kill -15 <pid></pid>(即kill <pid></pid>)、Ctrl+C(开发环境)、POST /actuator/shutdown(需引入 actuator 并开启端点) - ❌ 绝对禁止:
kill -9 <pid></pid>或taskkill /f—— JVM 层面直接终止,所有钩子、回调、finally 块均失效,必然导致请求中断和资源泄漏
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











