我正在尝试设置和检索当前正在运行的spring batch微线程的进度信息。
我有一个简单的春季批作业的基础上一步,例如。
public Step jobStep() {
return stepBuilderFactory.get(JOB_STEP_1)
.tasklet((contribution, chunkContext) -> {
...
}).build();
}微线程是一个简单的循环,做一些事情,这可能需要很多时间。
在循环中的每一次迭代之后,我都会在JobExecutionContext中设置一些进度信息。
chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext().put("myJobStatus", "10 of 100 finished");从另一个线程(例如,rest服务),我想检查实际微线程的进度,我使用JobExplorer来实现这一点
String status = (String)jobExplorer.getJobExecution(jobId).getExecutionContext().get("myJobStatus");遗憾的是,只有在步骤或作业完成时才设置myJobStatus属性。我甚至尝试将简单的循环替换为步骤的循环,但结果是相同的。
是否有其他方法可以设置和访问当前正在运行的作业的进度信息?
我正在使用基于JDBC的JobRepository等的DefaultBatchConfigurer。
发布于 2019-10-24 01:27:35
这一步听起来像是一个很好的候选者,可以重构为更多的Reader->Writer步骤,而不是Tasklet中的循环。在X项的每一块之后,Spring Batch框架将使用最新的读/写计数来更新步骤执行。
对于长时间运行的步骤,这还具有与每个块一起提交的优点,使可重启的负担更轻,而不是等到所有工作完成后,Tasklet才发出单个大的提交。
发布于 2019-10-24 18:31:47
您的问题是将进度信息保存在作业执行上下文中,该信息在步骤完成后保存在作业存储库中。您需要改用步骤执行上下文,因为它是在每次提交微线程时保存的。以下是参考文档中Execution context部分的摘录:
他们是两个不同的ExecutionContexts。作用域在步骤中的每个提交点都会被保存,而作用域到作业的作用域会在每个步骤执行之间保存。
因此,如果您将进度信息存储在步骤执行上下文(而不是作业执行上下文)中,则应该能够使用作业资源管理器从另一个线程获取进度信息。我假设您的微线程做了一些工作,将进度保存在步骤执行上下文中,然后返回CONTINUABLE,直到没有更多的工作要做,并在此时返回FINISHED。我在this repo中有一个完整的示例,但下面是相关部分:
class MyTasklet implements Tasklet {
private int progress;
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
RepeatStatus repeatStatus;
if (moreWork()) {
doSomeWork();
repeatStatus = RepeatStatus.CONTINUABLE;
} else {
repeatStatus = RepeatStatus.FINISHED;
}
reportProgress(chunkContext);
return repeatStatus;
}
private void reportProgress(ChunkContext chunkContext) {
chunkContext.getStepContext().getStepExecution()
.getExecutionContext().putInt("progress", this.progress++);
}
private void doSomeWork() throws Exception {
Thread.sleep(5000);
System.out.println("doing some work..");
}
private boolean moreWork() {
return this.progress < 100;
}
}https://stackoverflow.com/questions/58525263
复制相似问题