Reputation: 418
I've got Spring Boot application with Spring Batch framework. My goal is simple - run certain job concurrently. I want to be able to, let's say, run 15 threads in the same time and reject every excessive one. Here's my configuration class:
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configuration
@EnableBatchProcessing
public class GeneratingReportJobConfiguration {
@Autowired
private GeneratingReportTask task;
@Autowired
private JobRepository jobRepository;
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Bean
public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor(JobRegistry jobRegistry) {
JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor = new JobRegistryBeanPostProcessor();
jobRegistryBeanPostProcessor.setJobRegistry(jobRegistry);
return jobRegistryBeanPostProcessor;
}
@Bean
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(15);
taskExecutor.setMaxPoolSize(15);
taskExecutor.setQueueCapacity(0);
return taskExecutor;
}
@Bean
public JobLauncher jobLauncher(TaskExecutor taskExecutor) {
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
jobLauncher.setJobRepository(jobRepository);
jobLauncher.setTaskExecutor(taskExecutor);
return jobLauncher;
}
@Bean
public Job job() {
return jobBuilderFactory.get("generatingReportJob")
.start(step())
.build();
}
@Bean
public Step step() {
return stepBuilderFactory.get("generatingReportTask")
.tasklet(task)
.build();
}
}
The thing is, whatever I'm trying to do - application runs at most 10 jobs at the same time. I've tried experimenting with TaskExecutor
- my first logical choice was SimpleAsyncTaskExecutor
, which appeared to stash
every excessive request and then run them in a random order which is not intended.
So later I've tried to manipulate that limit and, as you can see in the code, I've started using ThreadPoolTaskExecutor
, which allowed me to set the limit to 5, for example, and it worked as expected - at most 5 threads could run at the same time and next ones were being rejected while these 5 were running. However, setting the limit to 15 resulted in behaviour similar to the previous one. Still, 11th request was being queued, whereas 16th was being rejected. This is almost my intended behaviour, however I need to be able to fully control thread execution.
Jobs are being invoked via @RestController
using jobLauncher.run()
. Every excessive request results in browser loading until being able to start execution. Seems like, program is being frozen somewhere inside jobLauncher.run()
(when able to start job execution it just exits - that's how async run works).
Upvotes: 5
Views: 5495
Reputation: 195
Bit late but try to check if you are using HikariCP which has a default 10 simultaneous DB connexions limit
Just faced similar issue and resolved by increasing spring.datasource.hikari.maximum-pool-size
See: Number of parallel threads processing is capped to 10 with Spring Batch
Upvotes: 2