java - Spring Batch 将并发线程数限制为 10
问题描述
我有带有 Spring Batch 框架的 Spring Boot 应用程序。我的目标很简单——同时运行某些工作。比如说,我希望能够同时运行 15 个线程并拒绝每一个过多的线程。这是我的配置类:
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();
}
}
问题是,无论我想要做什么 - 应用程序最多同时运行 10 个作业。我已经尝试过TaskExecutor
- 我的第一个合乎逻辑的选择是SimpleAsyncTaskExecutor
,它似乎隐藏了每个过多的请求,然后以不希望的随机顺序运行它们。
所以后来我试图操纵这个限制,正如你在代码中看到的那样,我已经开始使用ThreadPoolTaskExecutor
,它允许我将限制设置为 5,例如,它按预期工作 - 最多 5 个线程可以同时运行,而下一个在这 5 个运行时被拒绝。但是,将限制设置为 15 会导致与前一个类似的行为。尽管如此,第 11 个请求仍在排队,而第 16 个请求被拒绝。这几乎是我的预期行为,但是我需要能够完全控制线程执行。
通过@RestController
using调用作业jobLauncher.run()
。每个过多的请求都会导致浏览器加载,直到能够开始执行。看起来,程序在内部某处被冻结jobLauncher.run()
(当能够开始作业执行时,它就退出了——这就是异步运行的工作方式)。
解决方案
有点晚了,但请尝试检查您是否正在使用 HikariCP,它具有默认的 10 个同时 DB 连接限制
刚刚遇到类似的问题并通过增加解决spring.datasource.hikari.maximum-pool-size
推荐阅读
- json - 如何动态地将数据插入 JSON 文件?
- spring - 在 Spring 中从外部属性文件中读取 JNDI 名称
- ember.js - 有没有办法在 environment.js 中区分 ember 服务和 Ember 构建?
- file - 运行一个脚本,计算文件夹中所有/某些文件中令牌的出现次数并添加结果
- javascript - 更改标签的值
- c# - 如何在库上设置运行时绑定重定向
- python - 如何在自定义指标中获取会话?
- nativescript - 从 Nativescript 访问 FingerprintManager
- javascript - HTML代码中vue.js V-for和Flask之间的冲突?
- django - 在 Django 中,我有一个模型,其中基于某个字段,必须确定外键的下一个字段映射