在 Tomcat 关闭时关闭 Spring 启动中的执行器服务
Shutdown of Executor service in Spring Boot when Tomcat shuts down
我在Spring Boot中配置了一个executor服务如下:
@Configuration
@PropertySource({ "classpath:executor.properties" })
public class ExecutorServiceConfig {
@Value("${"executor.thread.count"}")
private int executorThreadCount;
@Bean("executorThreadPool")
public ThreadPoolExecutor cachedThreadPool() {
return new ThreadPoolExecutor(executorThreadCount, executorThreadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}
}
该应用程序部署在一个独立的 Tomcat 实例上。当 Tomcat 服务器关闭时,我发现队列中还有未完成的任务。结果,我将丢失数据。我有没有办法在此执行程序服务上调用 awaitTermination,以便它有机会完成队列中的内容?谢谢!
用@PreDestroy
注释进行注释。然后从那里关闭 executo 服务。
@Configuration
class ExecutorServiceConfiguration {
@Value("${"executor.thread.count"}")
private int executorThreadCount;
public static class MyExecutorService {
private ThreadPoolExecutor executor;
public MyExecutorService(ThreadPoolExecutor executor) {
this.executor = executor;
}
@PreDestroy()
public destroy() {
// destroy executor
}
}
@Bean("executorThreadPool")
public ThreadPoolExecutor cachedThreadPool() {
return new ThreadPoolExecutor(executorThreadCount, executorThreadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}
@Bean
public MyExecutorService configureDestroyableBean(ThreadPoolExecutor cachedThreadPool)
{
return new MyExecutorService(cachedThreadPool);
}
}
您可以通过根据需要配置 TomcatEmbeddedServletContainerFactory
bean. It has a method addContextLifecycleListeners which allows you to instantiate your own LifecycleListener and handle any Tomcat Lifecycle Events 来连接到 Tomcat 生命周期(例如,通过在 ExecutorService
上调用 awaitTermination
)。
@Configuration
public class TomcatConfiguration implements LifecycleListener {
@Autowire("executorThreadPool")
private ThreadPoolExecutor executor;
@Bean
public EmbeddedServletContainerFactory embeddedTomcatFactory() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.addContextLifecycleListeners(this);
return factory;
}
@Override
public void lifecycleEvent(LifeCycleEvent event) {
//if check for correct event
executor.awaitTermination();
}
}
我在Spring Boot中配置了一个executor服务如下:
@Configuration
@PropertySource({ "classpath:executor.properties" })
public class ExecutorServiceConfig {
@Value("${"executor.thread.count"}")
private int executorThreadCount;
@Bean("executorThreadPool")
public ThreadPoolExecutor cachedThreadPool() {
return new ThreadPoolExecutor(executorThreadCount, executorThreadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}
}
该应用程序部署在一个独立的 Tomcat 实例上。当 Tomcat 服务器关闭时,我发现队列中还有未完成的任务。结果,我将丢失数据。我有没有办法在此执行程序服务上调用 awaitTermination,以便它有机会完成队列中的内容?谢谢!
用@PreDestroy
注释进行注释。然后从那里关闭 executo 服务。
@Configuration
class ExecutorServiceConfiguration {
@Value("${"executor.thread.count"}")
private int executorThreadCount;
public static class MyExecutorService {
private ThreadPoolExecutor executor;
public MyExecutorService(ThreadPoolExecutor executor) {
this.executor = executor;
}
@PreDestroy()
public destroy() {
// destroy executor
}
}
@Bean("executorThreadPool")
public ThreadPoolExecutor cachedThreadPool() {
return new ThreadPoolExecutor(executorThreadCount, executorThreadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}
@Bean
public MyExecutorService configureDestroyableBean(ThreadPoolExecutor cachedThreadPool)
{
return new MyExecutorService(cachedThreadPool);
}
}
您可以通过根据需要配置 TomcatEmbeddedServletContainerFactory
bean. It has a method addContextLifecycleListeners which allows you to instantiate your own LifecycleListener and handle any Tomcat Lifecycle Events 来连接到 Tomcat 生命周期(例如,通过在 ExecutorService
上调用 awaitTermination
)。
@Configuration
public class TomcatConfiguration implements LifecycleListener {
@Autowire("executorThreadPool")
private ThreadPoolExecutor executor;
@Bean
public EmbeddedServletContainerFactory embeddedTomcatFactory() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.addContextLifecycleListeners(this);
return factory;
}
@Override
public void lifecycleEvent(LifeCycleEvent event) {
//if check for correct event
executor.awaitTermination();
}
}