[Spring Boot] 비동기 처리

Spring Boot Async

스프링 부트에서 비동기를 설정하기 위해선 다음과 같이 하면 된다.

  • @EnableAsync로 비동기 기능 활성화
  • 비동기 동작을 원하는 메소드 위에 @Async 어노테이션 추가

Spring Boot Async Configuration

스프링 부트에서 별 다른 설정 없이 @Async를 명시한다면 기본 설정인 SimpleAsyncTaskExecutor를 사용하게 된다. 하지만 별도의 ThreadPoolTaskExecutor를 설정한다면 이를 사용할 수 있게 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Configuration
@EnableAsync
public class AsyncConfig {

@Bean(name = "myThreadPoolTaskExecutor")
public Executor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(3);
taskExecutor.setMaxPoolSize(30);
taskExecutor.setQueueCapacity(10);
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
taskExecutor.setThreadNamePrefix("Executor-");
taskExecutor.initialize();
return taskExecutor;
}

}

기본적으로 설정해야할 옵션들은 다음과 같다.

  • CorePoolSize : 기본 스레드 수
  • MaxPoolSize : 최대 스레드 수
  • QueueCapacity : Queue의 크기

가령 위의 코드처럼 설정하게 된다면 스레드 풀의 기본 스레드는 3개로 시작하며 최대 10개 사이즈의 큐에서 작업이 대기할 수 있다. 이보다 더 많아지게 된다면 최대 30개의 스레드로 늘어나며 작업을 처리하게 된다. 그 이상으로 요청이 발생하게 된다면 RejectedExecutionException이 발생하게 된다.

RejectedExecutionException이 발생할 때 어떻게 처리할지에 대한 옵션은 setRejectedExecutionHandler()로 설정할 수 있다.

  • AbortPolicy
    • 기본 설정으로 RejectedExecutionException을 발생시킨다.
  • DiscardOldestPolicy
    • 오래된 작업을 무시한다.
    • 모든 작업이 반드시 처리될 필요가 없을 때 사용한다.
  • DiscardPolicy
    • 처리하려는 작업을 무시한다.
    • 모든 작업이 반드시 처리될 필요가 없을 때 사용한다.
  • CallerRunsPolicy
    • shutdown 상태가 아니라면 ThreadPoolTaskExecutor에 요청한 thread에서 직접 처리한다.

Shutdown 요청이 들어왔을 때도 모든 작업을 다 완료하고 종료하고 싶다면 다음과 같은 설정을 하면 된다. taskExecutor.setWaitForTasksToCompleteOnShutdown(true); 하지만 이런 설정에도 불구하고 모든 작업이 처리되기를 기다리기 어려운 상황이라면 timeout을 설정할 수 있다. taskExecutor.setAwaitTerminationSeconds(60);

Author: Song Hayoung
Link: https://songhayoung.github.io/2021/02/22/Spring/springbootAsync/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.