【问题标题】:Getting progress information from Spring Batch Tasklet从 Spring Batch Tasklet 获取进度信息
【发布时间】:2020-02-19 20:14:09
【问题描述】:

我正在尝试为当前正在运行的 spring 批处理 tasklet 设置和检索进度信息。

我有一个基于一步的简单春季批处理作业,例如。

   public Step jobStep() {
        return stepBuilderFactory.get(JOB_STEP_1)
                .tasklet((contribution, chunkContext) -> {
...
                }).build();
   }

tasklet 是一个简单的循环做一些事情,这可能需要很多时间。

在循环中的每次迭代之后,我都会在 JobExecutionContext 中设置一些进度信息,例如。

chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext().put("myJobStatus", "10 of 100 finished");

从另一个线程(例如休息服务)我想检查实际小任务的进度,我为此使用 JobExplorer

String status = (String)jobExplorer.getJobExecution(jobId).getExecutionContext().get("myJobStatus");

不幸的是,myJobStatus 属性仅在步骤或作业完成时设置。我什至尝试用步骤循环替换简单循环,但结果相同。

还有其他方法可以设置和访问当前正在运行的作业的进度信息吗?

我将 DefaultBatchConfigurer 与基于 JDBC 的 JobRepository 等一起使用。

【问题讨论】:

    标签: spring-boot spring-batch


    【解决方案1】:

    这一步听起来像是一个很好的候选,可以重构为更多的Reader->Writer 步骤,而不是Tasklet 中的循环。在每块 X 项之后,Spring Batch 框架将使用最新的读/写计数更新 Step Execution。

    对于长时间运行的步骤,这还具有提交每个块的优点,从而减少了可重新启动性的负担,而不是等到所有工作完成后才让 Tasklet 发出单个大型提交。

    【讨论】:

      【解决方案2】:

      您的问题是您将进度信息保存在作业执行上下文中,该信息在步骤完成后保存在作业存储库中。您需要改用 step 执行上下文,因为它在 tasklet 的每次提交时保存。以下是参考文档中Execution context 部分的摘录:

      它们是两个不同的 ExecutionContext。作用于 Step 的那个保存在 Step 中的每个提交点,而作用于 Job 的那个保存在每次 Step 执行之间。

      因此,如果您将进度信息存储在步骤执行上下文(而不是作业执行上下文)中,您应该能够使用作业资源管理器从其他线程获取它。我假设你的 tasklet 做了一些工作,将进度保存在步骤执行上下文中,然后返回 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;
          }
      }
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-19
      • 1970-01-01
      • 2020-05-26
      • 2019-10-24
      • 1970-01-01
      • 2016-04-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多