I have the following configuration in my Spring Boot app:
@Configuration
@EnableAsync
@Slf4j
public class AsyncConfig {
private static final int BUFFER = 1024;
@Bean
public AsyncTaskExecutor singleThreadAsyncTaskExecutor(Environment env) {
RingBufferAsyncTaskExecutor rbAsyncExecutor = new RingBufferAsyncTaskExecutor(env);
rbAsyncExecutor.setName("rb-executor");
rbAsyncExecutor.setBacklog(BUFFER);
rbAsyncExecutor.setProducerType(ProducerType.SINGLE);
rbAsyncExecutor.setWaitStrategy(new YieldingWaitStrategy());
log.info("Async task executor loaded");
return rbAsyncExecutor;
}
}
when I run it, the cpu usage hits 100% (sometimes 100 something):
investigating with visualvm, I see this
but, when I remove the instantiation of AsyncTaskExecutor
the CPU usage goes to 0.4% and the visualvm shows me barely 1% of CPU usage.
I found this problem while deploying it with docker, I saw my host usage hit the ceiling.
I tried lower the buffer size (it was 2048) to 1024 but nothing changed.
Without this bean, my @Async
services doesn't work asynchronously. (No TaskExecutor bean found for async processing
)
I think I solved.
What I did was use ThreadPoolTaskExecutor
instead RingBuffer, as follows
@Bean
public AsyncTaskExecutor getAsync(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(7);
executor.setMaxPoolSize(42);
executor.setQueueCapacity(11);
executor.setThreadNamePrefix("AsyncExec-");
executor.initialize();
return executor;
}
for some reason, the ThreadPoolTaskExecutor
is lighter than others.
I got this from spring framework doc