@Async 어노테이션 이란 ?
@Async 어노테이션은 스프링 프레임워크에서 비동기 처리를 위해 제공하는 어노테이션이다.
이 어노테이션을 메소드에 붙이면 스프링은 해당 메소드를 비동기적으로 실행한다.
@Async 어노테이션을 이해하기 위해서는 스프링의 AOP 와 스레드 풀의 개념을 알아야 한다.
스프링에서 @Async 를 사용하기 위해서는 @EnableAsync 어노테이션을 설정 클래스에 추가해야한다.
이 설정을 통해 스프링은 비동기 작업을 위한 설정을 활성화하고, AsyncTaskExecutor 인터페이스의 구현체를 사용하여 비동기 작업을 처리한다.
@EnableAsync 어노테이션을 통해 스프링이 비동기 처리를 위한 프록시 객체를 생성하고, 이를 통해 실제 메소드 호출을 비동기적으로 처리하기 때문이다.기본적으로 스프링은 SimpleAsyncTaskExecutor 를 사용하지만, ThreadPoolTaskExecutor와 같은 다른 Executor를 사용하여 성능을 향상시킬 수 있다.
SimpleAsyncTaskExecutor는 매 요청 마다 새로운 스레드를 생성하는 반면, ThreadPoolTaskExecutor는 미리 생성된 스레드 풀을 사용하기 때문에 오버헤드를 줄이고 성능을 향상시킬 수 있다.
스레드 풀이란?
스레드 풀은 사전에 스레드를 생성하고 관리하는 기술이다. 이를 통해 요청마다 스레드를 새로 생성하는 비용을 줄이고, 시스템 자원의 효율적인 사용을 가능하게 한다. 스프링은 ThreadPoolTaskExecutor를 통해 스레드 풀을 쉽게 구성할 수 있다.
ThreadPoolTaskExecutor는 스레드 풀의 크기, 최대 풀 크기, 큐 용량 등을 설정할 수 있다.
스프링에서 스레드 풀을 설정하는 방법은 application.properties 또는 @Configuration 클래스를 통해 ThreadPoolTaskExecutor 빈을 정의하고, 필요한 속성을 설정하는 것이다.
스레드 풀 설정 예제
@Configuration
public class AsyncConfig {
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(50);
taskExecutor.setMaxPoolSize(500);
taskExecutor.setQueueCapacity(0);
taskExecutor.setThreadNamePrefix("test Executor - ");
taskExecutor.setKeepAliveSeconds(30);
taskExecutor.setAllowCoreThreadTimeOut(true);
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
taskExecutor.initialize();
return taskExecutor;
}
}
corePoolSize
- 생성해서 사용할 스레드 풀에 속한 기본 스레드 갯수
- default 값은 1
maxPoolSize
- 최대 스레드 갯수
- default 값은 Integer.MAX_VALUE(약 21억)
queueCapacity
- 이벤트 대기 큐 크기
- default 값은 Integer.MAX_VALUE(약 21억)
keepaliveseconds
- 스레드 풀에서 유휴 상태의 스레드가 유지되는 시간
setThreadNamePrefix
- 스레드 이름의 접두사를 설정
- 스레드 풀에서 생성되는 각 스레드의 이름을 일관되게 관리할 수 있도록 도와준다.
rejectedExecutionHandler
- 태스크 처리량이 스레드 갯수가 max로 채워지고 queue 대기수를 넘어서는 경우에 RejectExecutionException 이 발생
- 해당 Exception을 다양한 방식으로 처리할수있도록 제공하는 Handler 클래스의 종류
- AbortPolicy
- default
-
- RejectExecutionHandler 예외 발생 시킴
- DiscardOldestPolicy
- 오래된 작업을 skip
- 모든 태스크가 반드시 처리될 필요가 없을때 사용
- DiscardPolicy
- 처리하려는 작업을 skip\
- 모든 태스크가 반드시 처리될 필요가 없을때 사용
- CallerRunsPolicy
- shutdown 상태가 아니라면 요청한 Caller Thread에서 직접 처리함
- 태스크 유실을 최소화하기 위해선 이 구현체를 사용해야함
- AbortPolicy
AllowcoreThreadTimeout
- 기본 스레드가 유휴 상태일 때 종료할지 여부를 설정하는 옵션
waitForTasksToCompleteOnShutdown
- 애플리케이션이 종료될 때 실행 중이던 작업을 모두 완료하고 종료할지 여부를 설정하는 옵션
- 기본값 : false -> 애플리케이션이 종료되면 실행 중이던 작업을 즉시 중단
- true 로 설정하면 남아있는 작업을 모두 완료한 후 종료
'SPRING' 카테고리의 다른 글
스프링 DB 2편 - 데이터 접근 활용 기술 (8) (0) | 2023.07.06 |
---|---|
스프링 DB 2편 - 데이터 접근 활용 기술 (7) (0) | 2023.07.04 |
스프링 DB 2편 - 데이터 접근 활용 기술 (6) (0) | 2023.06.29 |
스프링 DB 2편 - 데이터 접근 활용 기술 (5) (0) | 2023.06.25 |
스프링 DB 2편 - 데이터 접근 활용 기술 (4) (0) | 2023.06.21 |