2021年7月9日
お仕事でSpringの非同期処理とリトライ処理に触れることがあったので、まとめておきます。
Spring MVCの非同期処理の細かい話については、こちらを参照してください。
今回の環境
@org.springframework.scheduling.annotation.Asyncメソッドに付与することで非同期処理を行うことができます。 Spring Boot 2.1より前のバージョンだと、taskExecutorというBean名でThreadPoolTaskExecutort.javaをBean登録することが普通でしたが、Spring Boot 2.1からはデフォルトでBean登録されるようになりました。参考
1.@Asyncによる非同期処理を有効にする
設定用のクラスを準備して@EnableAsyncを付与します。
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration(proxyBeanMethods = false)
@EnableAsync
public class WebMvcConfig implements WebMvcConfigurer {}
2.非同期処理したいさせたいメソッドに@Asyncを付与する。
非同期処理させたいメソッドに@Asyncを付与してください。AOPを使っているので、DIしてこのメソッドを呼ぶ使い方をしないと非同期処理が行われません。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.b1a9idps.springasyncdemo.dto.request.AsyncRequest;
import com.b1a9idps.springasyncdemo.exception.FailedFileUploadException;
import com.b1a9idps.springasyncdemo.service.AsyncService;
@Service
public class AsyncServiceImpl implements AsyncService {
private static final Logger LOGGER = LoggerFactory.getLogger(AsyncServiceImpl.class);
@Override
@Async
public void save(AsyncRequest request) {
LOGGER.info("Start Async processing.(number = " + request.getNumber() + ")");
try {
Thread.sleep(5000);
LOGGER.info("Hi!.(number = " + request.getNumber() + ")");
} catch (InterruptedException e) {
LOGGER.error("thrown InterruptedException.");
}
LOGGER.info("End Async processing.(number = " + request.getNumber() + ")");
}
今回は、こんな感じの設定で試しています。
最小スレッド数2(spring.task.execution.pool.core-size=2)
最大スレッド数3(spring.task.execution.pool.max-size=3)
キュー数4(spring.task.execution.pool.queue-copacity=4)
スクリプトで連続的にリクエストしてみます。