Spring Boot で @Async
をつけた処理は非同期で実行されますが、
そのままだとアプリ停止時に容赦なく途中で落ちます。
悲劇……それを回避したい。
以下の手順で実現できます。
-
@Async
で使われるプールを指定 - アプリ停止時に、プール内のタスクが完了するまで待つようにする
プールの定義
@Bean
public ThreadPoolTaskExecutor asyncExecutor() {
ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor();
// 最大3タスク
threadPool.setCorePoolSize(3);
threadPool.setMaxPoolSize(3);
// アプリ終了時にshutdown
threadPool.setWaitForTasksToCompleteOnShutdown(true);
// shutdown時に実行完了を最大15分待つ
threadPool.setAwaitTerminationSeconds(60 * 15);
return threadPool;
}
setAwaitTerminationSeconds
も設定しないと、結局待たないので注意
@Async
の設定でプールを指定
@Configuration
@EnableAsync
class AsyncConfigurer extends AsyncConfigurerSupport {
@Autowired
private ThreadPoolTaskExecutor asyncExecutor;
@Override
public Executor getAsyncExecutor() {
return asyncExecutor;
}
}
@Async
で実行するプールを指定する事もできる。これはデフォルトで使われる物を指定。
ThreadPoolTaskExecutor
を getAsyncExecutor
で作ればよくね?とも思ったけど、停止時のあれこれが動かなくなる。Beanである事が大事。
これで動かした感じ、kill -15
しても終わってから落ちる。イェイ!