Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

spring boot app consuming all the cpu when AsyncTaskExecutor is configured

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):

enter image description here

investigating with visualvm, I see this

enter image description here

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)

like image 235
Luiz E. Avatar asked Oct 30 '22 20:10

Luiz E.


1 Answers

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

like image 72
Luiz E. Avatar answered Nov 15 '22 11:11

Luiz E.