我的Spring批处理应用程序消耗太多资源(+4转到Ram)。
当我查看jvm时,该应用程序会创建10个线程。
jobExecutionListener用于在执行结束时停止批处理
@Bean
public Job mainJob() throws IOException {
SimpleJobBuilder mainJob = this.jobBuilderFactory.get("mainJob")
.start(previousStep())
.next(partitionStep())
.next(finalStep())
.listener(jobExecutionListener(taskExecutor()));;
return mainJob.build();
}
@Bean
public Step partitionStep() throws IOException {
Step mainStep = stepBuilderFactory.get("mainStep")
.<InOut, InOut>chunk(1)
.reader(ResourceReader())
.processor(processor())
.writer(itemWriter())
.build();
return this.stepBuilderFactory.get("partitionStep")
.partitioner(mainStep)
.partitioner("mainStep", partitioner())
.build();
}
@Bean(name = "taskExecutor")
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(1);
taskExecutor.setMaxPoolSize(1);
taskExecutor.setQueueCapacity(1);
taskExecutor.setThreadNamePrefix("MyBatch-");
taskExecutor.initialize();
return taskExecutor;
}
//This jobExecutionListener stop the batch
@Bean
public JobExecutionListener jobExecutionListener(@Qualifier("taskExecutor")
ThreadPoolTaskExecutor executor) {
return new JobExecutionListener() {
private ThreadPoolTaskExecutor taskExecutor = executor;
@Override
public void beforeJob(JobExecution jobExecution) {
}
@Override
public void afterJob(JobExecution jobExecution) {
taskExecutor.shutdown();
System.exit(0);
}
};
}
@Bean
public Partitioner partitioner() {
MultiResourcePartitioner partitioner = new MultiResourcePartitioner();
ResourcePatternResolver patternResolver = new
PathMatchingResourcePatternResolver();
try {
partitioner.setResources(patternResolver.getResources(FILE +
configProperties.getIn()+ "/*.xml"));
} catch (IOException e) {
throw new RuntimeException("I/O problems when resolving the input file pattern.",e);
}
partitioner.setKeyName("file");
return partitioner;
}
如何在单线程中应用我的应用程序?任务执行程序不起作用。
答案 0 :(得分:1)
您的应用创建了10个线程,但不一定是Spring Batch线程。根据您的配置,只应创建一个前缀为MyBatch-
的线程。
此外,您将任务执行程序声明为Bean,但未在分区步骤中设置它。您的partitionStep
应该类似于:
@Bean
public Step partitionStep() throws IOException {
Step mainStep = stepBuilderFactory.get("mainStep")
.<InOut, InOut>chunk(1)
.reader(ResourceReader())
.processor(processor())
.writer(itemWriter())
.build();
return this.stepBuilderFactory.get("partitionStep")
.step(mainStep) // instead of .partitioner(mainStep)
.partitioner("mainStep", partitioner())
.taskExecutor(taskExecutor())
.build();
}
如何在单线程中应用我的应用程序?任务执行程序不起作用。
在分区步骤上设置任务执行器之后,您应该看到此步骤正在由ThreadPoolTaskExecutor
中定义的唯一线程执行。但是,我看不到将单个线程用于分区步骤的好处,因为这种设置的通常目标是并行处理分区(在本地具有多个线程,或者在远程具有多个辅助JVM)。
作为旁注,最好在afterJob
中用Job侦听器关闭任务执行器,但不要System.exit
。您需要让JVM正常关闭。
希望这会有所帮助。