리팩토링하던 중 Async를 남발하고 있던 걸 발견.
아래 코드는 기존에 ThreadPoolTaskExecutor이 아닌 AsyncTaskExecutor를 사용하고 있었다.
@EnableAsync
public class ExecutorConfig {
@Bean(name = "consumerThreadPool")
public ThreadPoolTaskExecutor consumerThreadPool() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(2);
executor.setThreadNamePrefix("consumer-");
executor.initialize();
return executor;
}
}
AsyncTaskExecutor로 생성한 " consumerThreadPool "을 사용하는 곳은 @Async가 사용된 KafkaConsumerClient.process()로, KafkaConsumerClient.process() 의 내부 로직은 아래와 같이 동기적으로 작동하는 블로킹 작업이 존재했다.
1. consumer.poll()
2. consumer.commitSync()
확인해보니 동기 방식이 필요했고, @Async와 AsyncTaskExecutor을 사용할 필요가 없어서 삭제
또한, 비동기 처리를 삭제해서 발생하는 관련 예외들은 내부에서 InterruptedException & Exception 처리 중이라 잘 방어하고 있다고 생각된다.
추가로 ThreadPoolTaskExecutor와 AsyncTaskExecutor의 차이를 간단하게 정리하자.
ThreadPoolTaskExecutor
- Executor 인터페이스를 구현한 클래스로, 스레드 풀을 관리
- 사용자가 직접 스레드 풀의 크기(코어/최대), 큐 용량 등을 설정 가능
- Spring에서 비동기 작업을 처리할 때 자주 사용
- 내부적으로는 ExecutorService를 사용
AsyncTaskExecutor
- Executor 인터페이스를 확장한 인터페이스로, 비동기 작업을 처리
- ThreadPoolTaskExecutor도 이 인터페이스를 구현하므로, 둘의 역할은 유사
- But, 스프링의 비동기 실행을 위한 더 추상적인 인터페이스로 사용되며, 여러 구현체가 존재할 수 있음
'⭐ Programming > Spring' 카테고리의 다른 글
property 우선 순위 (feat. application.properties) (0) | 2023.05.08 |
---|---|
HikariCP - DB ConnectionPool (1) | 2023.05.08 |
IoC 컨테이너와 @Bean, @Component (0) | 2023.05.08 |
DI와 IOC와 DIP (feat. 프레임워크와 라이브러리) (0) | 2023.05.07 |
JPA와 Mybatis 차이 = ORM과 SQL MAPPER 차이 (0) | 2023.02.09 |