Spring Boot 3.4 + Java 21虚拟线程:如何实现优雅停机?
Spring Boot 3.4 + Java 21虚拟线程:如何实现优雅停机?
你遇到的这个问题确实是Spring Boot启用虚拟线程后,优雅停机逻辑的一个典型场景——默认情况下虚拟线程的生命周期管理和平台线程池差异很大,导致停机时直接跳过了任务等待环节。下面给你一套具体的解决方案,覆盖Web API和定时任务两种核心场景:
一、配置基础优雅停机参数
首先在application.properties里添加全局超时配置,给所有任务留出足够的收尾时间:
# 设置每个停机阶段的超时时间,可根据业务调整,示例为30秒 spring.lifecycle.timeout-per-shutdown-phase=30s
二、处理Web API的优雅停机
启用虚拟线程后,Web服务器默认不会等待正在处理的请求完成,需要显式开启Web层的优雅停机逻辑:
# 让Web服务器停止接收新请求,同时等待现有请求处理完成 spring.web.server.shutdown=graceful
这个配置会让Tomcat(或你使用的其他Web容器)在停机时,先关闭端口拒绝新请求,同时等待所有正在处理的虚拟线程请求完成,直到达到设置的超时时间。
三、处理@Scheduled定时任务的优雅停机
默认的@Scheduled注解使用的调度器不会针对虚拟线程做优雅等待,需要自定义支持优雅停机的虚拟线程调度器:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; @Configuration public class VirtualThreadSchedulerConfig { @Bean public TaskScheduler virtualThreadTaskScheduler() { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.setThreadNamePrefix("virtual-scheduled-"); // 指定使用虚拟线程工厂创建调度线程 scheduler.setThreadFactory(Thread.ofVirtual().factory()); // 开启停机时等待任务完成的逻辑 scheduler.setWaitForTasksToCompleteOnShutdown(true); // 设置等待超时时间,和全局超时保持一致即可 scheduler.setAwaitTerminationSeconds(30); return scheduler; } }
配置后,你的@Scheduled任务会使用这个自定义调度器,在应用停机时,调度器会等待所有正在执行的定时任务完成,超时后才会终止。
额外提示
如果你的应用里还有自定义的虚拟线程任务(比如用Thread.ofVirtual().start()启动的任务),记得在任务逻辑里处理中断信号:比如定期检查Thread.currentThread().isInterrupted(),在收到中断时安全收尾任务;也可以监听Spring的ContextClosedEvent事件,在应用开始停机时主动触发任务的收尾逻辑。
备注:内容来源于stack exchange,提问作者John Little
相关产品推荐
相关产品推荐

