Spring Boot 优雅关闭的核心是让正在处理的请求完成、异步任务结束、资源释放完毕后再退出 JVM。需启用内置优雅停机(server.shutdown=graceful)、配置超时(spring.lifecycle.timeout-per-shutdown-phase)、监听关闭事件(如ContextClosedEvent)、管理自定义线程池与异步任务,并配合SIGTERM或Actuator端点触发,确保Kafka、RabbitMQ、@Scheduled等组件也支持等待关闭。

Spring Boot 应用的优雅关闭,核心是让正在处理的请求完成、异步任务结束、资源释放完毕后再真正退出 JVM,避免连接中断、数据丢失或线程被强制终止。关键在于启用并配置 优雅停机(Graceful Shutdown),同时合理管理自定义组件的生命周期。
启用 Spring Boot 内置优雅停机
从 Spring Boot 2.3 开始,内嵌 Web 容器(Tomcat、Jetty、Netty)原生支持优雅停机,只需开启配置:
- 对于 Tomcat(默认):在 application.yml 中添加
server: shutdown: graceful # 必须显式开启
- 同时建议设置等待上限,防止无限挂起(例如最多等 30 秒):
spring:
lifecycle:
timeout-per-shutdown-phase: 30s启用后,当收到操作系统 SIGTERM(如 kill -15 <pid></pid>)或通过 Actuator 的 /actuator/shutdown 端点触发关闭时,Web 容器会停止接收新请求,并等待现存请求自然完成。
监听应用关闭生命周期事件
利用 Spring 的上下文关闭事件,在停机前执行清理逻辑:
- 注册
@EventListener监听ContextClosedEvent或更精准的ApplicationPreStopEvent(Spring Boot 3.2+) - 适合场景:关闭自定义线程池、清空本地缓存、提交未刷盘的日志、通知下游服务下线
示例:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
@Component
public class GracefulShutdownListener {
@EventListener
public void handleContextClose(ContextClosedEvent event) {
// 执行清理,比如调用 dataSource.close()、executor.shutdown()
log.info("Spring context closed, cleanup done.");
}
}管理自定义线程与异步任务
Spring Boot 不会自动等待你手动创建的线程或 @Async 任务结束。必须主动干预:
- 使用
TaskExecutor替代裸线程,确保其纳入 Spring 生命周期管理(如ThreadPoolTaskExecutor) - 重写
destroy()方法,调用shutdown()+awaitTermination() - 对
@Async方法,确保底层线程池已配置为可等待关闭(setWaitForTasksToCompleteOnShutdown(true))
常见遗漏点:Kafka Listener、RabbitMQ SimpleMessageListenerContainer、定时任务(@Scheduled)也需显式配置关闭等待行为。
配合 Actuator 和外部信号使用
启用 actuator 后,可通过 HTTP 主动触发关闭(仅限开发/测试环境,生产慎用):
- 添加依赖:
spring-boot-starter-actuator - 开放端点:
management.endpoints.web.exposure.include=shutdown - 发送 POST:
curl -X POST http://localhost:8080/actuator/shutdown
生产环境推荐用系统信号(kill -15),并配合进程管理工具(如 systemd)设置 TimeoutStopSec 与 Spring 的 timeout-per-shutdown-phase 对齐,避免被强制 kill -9。

















