Завершение работы службы Executor в Spring Boot, когда Tomcat выключается - PullRequest
0 голосов
/ 15 февраля 2019

Я настроил службу исполнителя в Spring Boot следующим образом:

@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 в этой службе исполнителя, чтобы он получил возможность завершить то, что находится в очереди?Спасибо!

Ответы [ 2 ]

0 голосов
/ 16 февраля 2019

Вы можете подключиться к жизненному циклу Tomcat, настроив свой компонент TomcatEmbeddedServletContainerFactory.У него есть метод addContextLifecycleListeners, который позволяет создавать экземпляры вашего собственного LifecycleListener и обрабатывать любые события жизненного цикла Tomcat так, как вы хотите (например, вызывая awaitTermination на вашем ExecutorService).

@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();
    }
}
0 голосов
/ 16 февраля 2019

Аннотировать с @PreDestroy аннотацией.Затем выполните отключение службы executeto оттуда.

@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);
    }

}
...