spring boot 2.3+ 优雅停机核心是“先拒新、再等旧、最后收资源”:需配置server.shutdown=graceful和spring.lifecycle.timeout-per-shutdown-phase(建议45s或60s),配合sigterm信号、合理线程池设置(如threadpooltaskexecutor需setwaitfortaskstocompleteonshutdown(true))及@predestroy等清理机制。

Spring Boot 2.3+ 版本已原生支持优雅停机,核心是让正在处理的请求跑完、新请求进不来、资源有序释放。配置简单但细节关键,尤其要注意超时设置和线程池行为。
基础配置:两行启用内置机制
只需在 application.yml 中添加:
- server.shutdown=graceful:通知内嵌 Web 容器(Tomcat/Jetty/Undertow/Reactor Netty)停止接受新连接,并关闭 keep-alive;
- spring.lifecycle.timeout-per-shutdown-phase=45s:设为略大于你最长请求耗时(如 45 秒或 60 秒),这是整个停机阶段的总等待上限,超时后强制收尾。
配置生效后,收到 kill -15 <pid></pid> 信号时,Web 层会立即拒绝新请求,同时继续服务已建立连接中的活跃请求。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
确保异步任务真正等完
仅靠上述配置,对部分场景仍可能“假等”——比如 WebFlux 应用或自定义线程池任务未被阻塞等待:
-
WebFlux(Reactor Netty):需在 Netty 资源释放处显式调用
block(),避免disposeLater().subscribe()非阻塞导致提前退出; -
@Async 线程池:若使用
ThreadPoolTaskExecutor,必须设置:setWaitForTasksToCompleteOnShutdown(true)和setAwaitTerminationSeconds(45)(值应 ≤ 上述 timeout); - Servlet 容器(如 Tomcat)一般能自动等待 Servlet 线程池中任务结束,无需额外干预。
补充清理逻辑:不只是等请求
优雅停机不止于 HTTP 请求,还需保障事务、连接、缓存等不中断:
- 用 @PreDestroy 或实现 DisposableBean 关闭手动管理的资源(如直连数据库、未托管的 Redis 连接);
- 监听 ContextClosedEvent 执行全局收尾:刷新本地缓存、提交延迟日志、通知下游服务下线;
- 对 Kafka 消费者、WebSocket 会话等,确认其自身支持 graceful shutdown 并已配置合理超时(如
spring.kafka.listener.stop-timeout)。
触发方式要合规,避免绕过流程
只有可捕获的终止信号才能激活优雅流程:
- ✅ 推荐:
kill -15 <pid></pid>(标准 SIGTERM); - ✅ 开发/运维常用:
curl -X POST http://localhost:8080/actuator/shutdown(需引入spring-boot-starter-actuator并开启端点); - ❌ 绝对禁止:
kill -9 <pid></pid>—— 直接杀死 JVM,所有等待与清理逻辑全部跳过。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










