Spring Boot优雅关闭核心是先停流量、再等处理、最后收资源,需配置server.shutdown=graceful和spring.lifecycle.timeout-per-shutdown-phase=30s,配合readinessProbe实现平滑下线。

Spring Boot 优雅关闭的核心是“先停流量、再等处理、最后收资源”,不是简单终止进程,而是让正在跑的请求跑完,同时不让新请求进来。关键不在关得多快,而在关得稳不稳——尤其在滚动更新、缩容或发布时,能避免用户看到 502/503 或连接重置。
基础配置:两行启用标准流程
Spring Boot 2.3+ 原生支持,无需额外依赖。只需在 application.properties 中加:
- server.shutdown=graceful —— 启用 Web 容器(Tomcat/Jetty/Netty/Undertow)的优雅关闭逻辑
- spring.lifecycle.timeout-per-shutdown-phase=30s —— 设置整个关闭阶段最大等待时间(含请求处理、Bean 销毁、线程池关闭等)
配置生效后,收到 SIGTERM(如 kill -15、docker stop、K8s terminationGracePeriodSeconds)时,自动执行:停止监听端口 → 拒绝新连接 → 等待活跃请求完成 → 销毁 Bean → 关闭线程池和连接池。
保护流量的关键动作:配合就绪探针(readinessProbe)
单靠优雅关闭还不够。如果负载均衡器还在转发请求,而应用已停止接收,就会丢请求。必须让流量提前下线:
- K8s 场景下,在 Pod 终止前,先调用
readinessProbe失败,让 Service 自动从 Endpoint 列表中摘除该实例 - 确保
readinessProbe能快速响应状态变化(例如检查一个 /actuator/health/readiness 端点),并在收到 SIGTERM 后立即返回失败 -
terminationGracePeriodSeconds必须 ≥spring.lifecycle.timeout-per-shutdown-phase(建议留 5–10 秒余量),否则 K8s 会提前发SIGKILL强杀
常见资源需显式清理
Spring 容器能自动调用 @PreDestroy 和 destroyMethod,但部分资源需你主动保障:
- 自定义线程池:用
@Bean(destroyMethod = "shutdown"),并确保任务能awaitTermination - Kafka 消费者、RabbitMQ 监听器:它们也受
timeout-per-shutdown-phase约束,但建议在@PreDestroy中手动调用stop()或close() - 临时文件、锁文件、本地缓存写回:放在
@PreDestroy方法里做持久化或释放
慎用 /actuator/shutdown 端点
虽然可通过 POST /actuator/shutdown 触发关闭,但生产环境一般禁用:
- 该端点无鉴权(除非你配了 Spring Security),暴露即风险
- 它只是触发
ApplicationContext.close()的一种方式,和kill -15效果一致,并不更“优雅” - 推荐仅用于开发调试;线上应依赖容器编排平台(如 K8s)的标准生命周期管理


















