You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 11:00:27