SimpleAsyncTaskExecutor는 Thread Pool이 아니다.

SimpleAsyncTaskExecutor는 단순히 Thread를 계속 만들어내는 객체이다. Thread는 자원이 많이 들기 때문에 가급적이면 Thread Pool 관리하에 사용이 되어야 한다.

그렇다면, 이를 확인해보자. 일단 가시화를 해보기 위해 VisualVM을 사용해보고자 한다.

설정

기본적인 설정은 Spring Boot - Async에서 간략하게 다뤄봤다. 보다 자세한 내용을 원한다면 공식 문서나 가이드를 참고하기를 권장한다.

SimpleAsyncTaskExecutor

Bean 등록
1
2
3
4
@Override
public Executor getAsyncExecutor() {
return new SimpleAsyncTaskExecutor("heowc-async-");
}
가시화

테스트는 10번의 HTTP 호출해본다. 당연한 결과이지만 앞서 말한바와 같이 10개의 Thread가 생성된 것을 볼 수 있다.

Alt SimpleAsyncTaskExecutor 결과

Custom Thread Pool

그렇다면 Thread Pool을 만들면 어떤 결과가 나오게 될까?

Bean 등록
1
2
3
4
5
6
7
8
9
10
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("heowc-async-");
executor.initialize();
return executor;
}
가시화

앞서 했던 테스트와 동일하게 진행 했다. 결과는 10개 보다 작은 Thread를 생성하게 된다.

Alt Custom Thread Pool 결과

AsyncRestTemplate

AsyncRestTemplateRestTemplate를 비동기로 처리하기 위한 방법이다. (Spring 5에서는 deprecated되었고 WebClient를 사용해야 한다.)

AsyncRestTemplate 또한 Async와 동일하게 SimpleAsyncTaskExecutor를 기본적으로 사용한다. 물론 Thread Pool를 만들어주는 것도 좋지만, AsyncRestTemplate를 보다 효율적으로 사용하기 위해서는 NIO 라이브러리를 사용하는 것이 좋다.

Dependency

NIO 라이브러리는 ApacheNetty에서 제공한다.

1
2
3
4
dependencies {
compile('org.apache.httpcomponents:httpasyncclient:4.1.3')
compile('io.netty:netty-all:4.1.11.Final')
}
Config

Apache에서 제공해주는 것은 HttpCoponentsAsyncClientHttpRequestFactory를 사용하면 되고, Netty에서 제공해주는 것은 Netty4ClientHttpRequestFactory를 이용하면 된다.

1
2
3
4
5
@Bean
public AsyncRestTemplate asyncRestTemplate() {
// return new AsyncRestTemplate(new Netty4ClientHttpRequestFactory());
return new AsyncRestTemplate(new HttpComponentsAsyncClientHttpRequestFactory());
}
가시화

SimpleAsyncTaskExecutor 사용

HttpCoponentsAsyncClientHttpRequestFactory 사용