【发布时间】:2021-10-26 12:46:51
【问题描述】:
我正在做一个包含 Spring 批处理的项目,在复制代码 sn-ps 之前,我将简单地总结一下这项工作是如何使用 cron 工作的。
- cron 在我的项目上调用了一个 rest API (@PostMapping("/jobs/external/{jobName}"))
- 在 post 方法中,我得到工作并执行它。
- 在每次执行中,我应该运行一个步骤。
- 该步骤包含一个读取器(对弹性 API 的外部 rest 调用以获取文档)和一个处理器。
现在我的问题是:在catalina.out 中,我可以按照我的 cron 中的配置每 10 分钟查看一次来自 cron 的其余调用。但是,该步骤似乎不是每 10 分钟调用一次弹性,批处理始终具有相同的数据集,在 tomcat 重新启动期间调用批处理时会获取一次。
工作休息接口:
@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 分钟调用一次。
【问题讨论】:
-
因为你的
rowItemReaderbean 是一个单例,而不是工作或步骤范围。 -
很抱歉,我真的不掌握春季批次。一个单例对我来说意味着一个实例,但是这个实例应该每 10 分钟调用一次吗?
-
没有。此实例将创建一次,每 10 分钟重复使用一次。配置不是每 10 分钟加载一次。因此,您需要将作业的 bean 步骤设置为范围,以便每次执行时都会重新创建该 bean,从而执行请求。
-
谢谢你 M. Deinum,我用 @StepScope 注释了我的 steap bean,它起作用了。
标签: spring spring-batch