我有一个报告生成应用程序。由于准备此类报告是重量级的,因此它们与Spring Batch异步准备。使用HTTP通过REST接口创建此类报告的请求。
目标是REST资源简单地将报告执行排队并完成(as described in documentation)。因此,为JobLauncher提供了一个TaskExecutor:
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
<property name="taskExecutor">
<bean class="org.springframework.core.task.SimpleAsyncTaskExecutor"/>
</property>
</bean>
由于报告非常重要,因此在给定时间内只能生成指定数量的报告。希望能够将Spring Batch配置为一次只生成2个实例,已指定 concurrencyLimit :
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
<property name="taskExecutor">
<bean class="org.springframework.core.task.SimpleAsyncTaskExecutor">
<property name="concurrencyLimit" value="2" />
</bean>
</property>
</bean>
不幸的是,当两个作业已经运行时,启动作业调用被阻止: jobLauncher.run(job,builder.toJobParameters());
显然jobLauncher会立即尝试执行作业。我想象一旦线程可用,它就会排队执行作业。这样,我可以通过简单地添加其他处理实例来扩展我的应用程序,所有这些都使用相同的作业存储库
类似的问题是asked here。我即将开始探索Spring Batch Integration,但我不确定这是否是正确的方向。
我的用例对我来说似乎并不常见,难道不应该有一个广泛讨论的模式,我显然无法找到它吗?
由于 ˚F
答案 0 :(得分:10)
SimpleAsyncTaskExecutor
不建议大量使用,因为它会为每个任务生成一个新线程。它也不支持更强大的概念,如线程池和任务排队。
如果你看一下ThreadPoolTaskExecutor
,它支持更强大的任务执行范例,例如排队任务和使用线程池而不是产生随机的,未重用的线程。
您可以在此处详细了解javadoc中的ThreadPoolTaskExecutor
:http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.html
答案 1 :(得分:4)
这有所帮助,非常感谢。在替换SimpleAsyncTaskExecutor后,我正是我需要的。代码:
@Bean
public TaskExecutor jobLauncherTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setMaxPoolSize(executorsPoolSize);
executor.setCorePoolSize(executorsPoolSize);
return executor;
}
由于 ˚F