Spring Boot升级后调用actuator/shutdown,Java进程仍存活问题咨询
Spring Boot 2.6.7调用Actuator Shutdown后Java PID仍运行的原因及排查方案
- 非守护线程残留:Spring Boot 2.3到2.6版本的线程管理逻辑有调整。若应用存在自定义非守护线程(未调用
setDaemon(true)的Thread实例),或第三方依赖启动了非守护线程,Spring Boot容器停止后这些线程会持续运行,导致JVM无法退出。 - Shutdown钩子执行阻塞:Spring Boot依赖JVM shutdown钩子完成资源清理,若某个Bean的
@PreDestroy方法、DisposableBean实现,或自定义ShutdownHook中存在阻塞操作(如等待锁、未完成的IO操作),会导致钩子执行卡住,JVM无法正常终止。 - Actuator Shutdown异步执行异常:从Spring Boot 2.4开始,Shutdown端点默认异步执行(可通过
management.endpoint.shutdown.async=false关闭)。若异步执行过程中出现未处理的异常,可能导致容器标记为停止但JVM未退出。 - 资源未正确释放:数据库连接池未关闭、Socket连接残留、文件流未释放等资源持有情况,会阻止JVM退出。部分旧版依赖在Spring Boot 2.6环境下,资源释放逻辑可能存在兼容性问题。
- JVM或系统层面问题:极少数情况下,JVM自身bug、系统资源限制(如内存不足导致清理失败)也会造成进程残留。
排查步骤
- 检查应用日志,确认Shutdown过程中是否存在异常或警告,比如Bean销毁失败的日志信息。
- 执行
jstack <PID>命令导出线程栈,查看活跃线程类型(是否为非守护线程)及状态(如阻塞在哪个方法)。 - 核查自定义线程创建逻辑,确保非必要线程设置为守护线程,或在应用关闭时手动终止。
- 临时添加配置
management.endpoint.shutdown.async=false关闭异步执行,重新测试Shutdown功能。 - 排查升级后新增或版本变更的第三方依赖,确认是否存在资源泄漏或线程未终止问题。
内容的提问来源于stack exchange,提问作者Kotesh
相关产品推荐
相关产品推荐

