我在Spring中用ThreadPoolTaskExecutor声明了SimpleRabbitListenerContainerFactory。当我查看yourkit上的线程时,会看到所有ThreadPoolTaskExecutor线程,当我在队列中发送消息时,它会同时使用它们。所以一切都很好。
问题是我想在关闭服务器之前等待服务器发送的所有消息得到处理,因此我们不会丢失消息(因为我们正在使用同步队列,而不是异步,客户端正在等待答案)。因此,我在执行程序上将setWaitForTasksToCompleteOnShutdown参数设置为true,并实现了上下文侦听器以在发生上下文破坏事件时关闭执行程序。
现在,当我关闭服务器时,它不会破坏服务,因此消息仍会从队列中弹出并处理,但它从未真正关闭服务器。它达到超时并杀死所有剩余线程。就像不了解托管线程中的所有任务都已完成一样。
我试图用yourkit查看线程,似乎我的执行者声明的所有线程都已完成,但由Rabbit启动的(名称为Rabbitmq-thread)却没有。
我有一个问题是:由执行者管理的线程与由Rabbit管理的线程之间有什么区别?两者如何关联?
@Bean("analysisExecutor")
public ThreadPoolTaskExecutor analysisExecutor() {
final ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
pool.setCorePoolSize(analysisRabbitProperties.getAnalysisRequestMinWorkers() + analysisRabbitProperties.getManualAnalysisResponseMinWorkers());
pool.setMaxPoolSize(analysisRabbitProperties.getAnalysisRequestMaxWorkers() + analysisRabbitProperties.getManualAnalysisResponseMaxWorkers());
pool.setQueueCapacity(10);
pool.setWaitForTasksToCompleteOnShutdown(true);
pool.setThreadNamePrefix("AnalysisExecutor-");
pool.setAwaitTerminationSeconds(120);
return pool;
}
@Bean("analysisReqFactory")
public SimpleRabbitListenerContainerFactory analysisReqListenerFactory() throws Exception {
final SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(analysisConnectionFactory());
factory.setMessageConverter(analysisRequestProtoConverter());
factory.setConcurrentConsumers(analysisRabbitProperties.getAnalysisRequestMinWorkers());
factory.setMaxConcurrentConsumers(analysisRabbitProperties.getAnalysisRequestMaxWorkers());
factory.setTaskExecutor(analysisExecutor());
return factory;
}
@WebListener
public class GracefulShutdownListener implements ServletContextListener {
@Autowired
private ThreadPoolTaskExecutor analysisExecutor;
@Override
public void contextDestroyed(final ServletContextEvent sce) {
analysisExecutor.shutdown();
}
}
我主要想了解如何使waitForTasksToCompleteOnShutdown工作。
谢谢