spring - Spring-batch 步骤未重新执行(缓存)
问题描述
我正在开发一个包含 Spring 批处理的项目,在复制代码片段之前,我将简单地总结一下这项工作是如何与 cron 一起工作的。
- cron 在我的项目上调用了一个 rest API (@PostMapping("/jobs/external/{jobName}"))
- 在 post 方法中,我得到了工作并执行它。
- 在每次执行中,我应该运行一个步骤。
- 该步骤包含一个阅读器(对弹性 API 的外部休息调用以获取文档)和一个处理器。
现在我的问题是:在cron 中catalina.out
,我可以每隔 10 分钟看到一次来自 cron 的其余调用,如我的 cron 中配置的那样。但是,该步骤似乎不是每 10 分钟调用一次弹性,批处理始终具有相同的数据集,在 tomcat 重新启动期间调用批处理时会获取一次。
工作休息api:
@PostMapping("/jobs/external/{jobName}")
@Timed
public ResponseEntity start(@PathVariable String jobName) throws BatchException {
log.info("LAUNCHING JOB FROM EXTERNAL : {}, timestamp : {}", jobName, Instant.now().toString());
try {
Job job = jobRegistry.getJob(jobName);
JobParametersBuilder builder = new JobParametersBuilder();
builder.addDate("date", new Date());
return Optional.of(jobLauncher.run(job, builder.toJobParameters()))
.map(BatchExecutionVM::new)
.map(exec -> ResponseEntity
.ok()
.headers(HeaderUtil.createAlert("jobManagement.started", jobName))
.body(exec))
.orElseGet(() -> ResponseEntity.badRequest().build());
} catch (NoSuchJobException aEx) {
log.warn(JOB_NOT_FOUND, aEx);
throw new BatchException();
} catch (JobInstanceAlreadyCompleteException | JobExecutionAlreadyRunningException | JobRestartException aEx) {
log.warn("Job execution error.", aEx);
throw new BatchException();
} catch (JobParametersInvalidException aEx) {
log.warn("Job parameters are invalid.", aEx);
throw new BatchException();
}
}
作业配置:
@Bean
public Job usualJob() {
return jobBuilderFactory
.get("usualJob")
.incrementer(new SimpleJobIncrementer())
.flow(readUsualStep())
.end()
.build();
}
@Bean
public Step readUsualStep() {
// TODO: simplifier on n'a pas besoin de chunk
return stepBuilderFactory.get("readUsualStep")
.allowStartIfComplete(true)
.<AlertDocument, Void>chunk(25)
.readerIsTransactionalQueue()
.reader(rowItemReader())
.processor(rowItemProcessor())
.build();
}
@Bean
public ItemReader<AlertDocument> rowItemReader() {
return new UsualItemReader(usualService.getLastAlerts());
}
@Bean
public UsualMapRowProcessor rowItemProcessor() {
return new UsualMapRowProcessor();
}
我不知道为什么usualService.getLastAlerts()
只调用一次而不是每 10 分钟调用一次。
解决方案
感谢 M. Deinum,这基本上是解决方案:
@Bean
@StepScope
public ItemReader<AlertDocument> rowItemReader() {
return new UsualItemReader(usualService.getLastAlerts());
}
使用 stepScope 注释对 step bean 进行注释将使其每一步都重新实例化。