【问题标题】:Spring Batch: execute same job with different parametersSpring Batch:使用不同的参数执行相同的作业
【发布时间】:2018-09-10 19:38:45
【问题描述】:

我是 sprint 批次的新手,我找不到我的问题的答案。

我正在尝试使用 Spring Boot 和 Spring Batch 来实现 JOB。我的 JOB 需要一个参数,所以我正在执行这样的应用程序:

java -jar -Dspring.profiles.active=gus /applications/botbit-batch/botbit-batch-1.0.0.jar --spring.batch.job.names=persistCustomerSuccessMetrics date=2015-12-13

粗体是我需要的参数。

我第一次执行应用程序,但在以后的执行中,我的工作总是使用我在第一次执行时传递的参数。

日志显示:

Running default command line with: 
[spring.batch.job.names=persistCustomerSuccessMetrics, date=2015-12-13]

后面几行:

Job: [FlowJob: [name=persistCustomerSuccessMetrics]] launched with the following parameters: 
[{date=2015-12-12, -spring.batch.job.names=persistCustomerSuccessMetrics, run.id=2}]

日期 2015-12-12 是第一次执行的日期,我无法使用不同的参数再次执行该作业。

我的工作设置:

@Bean
@JobScope
public CustomerSuccessMetricsReader customerSuccessMetricsReader(@Value("#{jobParameters[date]}") String date) {
    return new CustomerSuccessMetricsReader(storeStatisticsUrl, restTemplate, date);
}
@Bean
public CustomerSuccessMetricsProcessor customerSuccessMetricsProcessor() {
    return new CustomerSuccessMetricsProcessor();
}
@Bean
public Job persistCustomerSuccessMetrics(Step persistCustomerSuccessMetricsStep1) {
    return jobBuilderFactory.get("persistCustomerSuccessMetrics").incrementer(new RunIdIncrementer())
            .listener(new CustomerSuccessMetricsCompletionListener()).flow(persistCustomerSuccessMetricsStep1).end().build();
}
@Bean
public Step persistCustomerSuccessMetricsStep1() {
    return stepBuilderFactory.
            get("persistCustomerSuccessMetricsStep1").
            <CustomerSuccessMetricsDTO, CustomerSuccessMetricsDTO> chunk(10).
            reader(customerSuccessMetricsReader(null)).
            processor(customerSuccessMetricsProcessor()).
            //writer(customerSuccessMetricsWriter).
            build();
}

我已尝试删除 incrementer(new RunIdIncrementer()) 在这种情况下,它可以正常工作,但我无法使用相同的参数重复执行。

所以,我需要使用以下 rqs 来实现这项工作:

  • 作业必须采用执行参数,而不是存储在数据库中的参数
  • 作业必须支持使用相同参数的多次执行。

我将不胜感激。 问候

【问题讨论】:

    标签: spring-batch


    【解决方案1】:

    [Background] 我也有同样的问题,我的作业有一个参数,我在命令行上传递如下:

    $ java -jar ./target/[java-executable-jar].jar 文件=[文件路径]

    我注意到,在新的 Spring Batch 元数据库上,这第一次可以正常工作,之后如果我使用不同的文件运行,Spring Batch 会使用存储在批处理存储库元数据库中的文件路径。

    如前所述,我尝试了所有上述建议的解决方案,但没有一个可行。我使用了“.incrementer(new RunIdIncrementer())”,它无法使作业执行独一无二。我还尝试将文件参数作为非识别参数传递,如下所示:

    $ java -jar ./target/[java-executable-jar].jar --file=[文件路径]

    我也尝试添加时间戳参数,但没有帮助 也没用。

    这似乎是批处理版本中的一个问题,因为根据文档我能够使作业执行唯一并且作业使用新文件(文件每次都不同,第一次运行时不一样。

    最后我不得不恢复到一个黑客来强制为我解决问题,如下所示:

    [解决方案] 每次运行应用时都强制以不同的方式命名作业。这样:

    @Bean
    public Job sampleJob() throws Exception {
       String jobName = "sampleJob" + System.currentTimeMillis();
       return jobBuilderFactory.get(jobName)
          .incrementer(new RunIdIncrementer())
          .start(step1()).on("COMPLETED").to(successFileArchiveStep())
          .from(step1()).on("*").to(failureFileArchiveStep())
          .end()
          .build();
    }
    

    【讨论】:

    • 我终于在命令行执行中使用系统java参数解决了这个问题。 java -DmyParamKey=myParamValue -jar .... 在应用程序代码中,我通过 System.getProperty(myParamKey) 得到这个值 ...它不是最好的解决方案,但它可以工作
    • 我遇到了类似的问题。我已经更改了作业名称,它开始工作了。
    【解决方案2】:

    我已尝试删除增量器(new RunIdIncrementer()) 在这种情况下它工作正常,但我无法使用相同的参数重复执行。

    按照设计,一旦作业实例完成,就不可能重新运行它(如果您尝试这样做,将抛出JobInstanceAlreadyCompleteException)。如果上次执行失败,您可以重新运行同一实例,但一旦完成,您将无法再次运行它。此处通过示例详细说明了这一点:https://docs.spring.io/spring-batch/4.0.x/reference/html/domain.html#jobinstance

    作业必须带有执行参数,而不是存储在数据库中的参数

    作业必须支持使用相同参数的多次执行。

    您可以做的是像现在一样继续使用RunIdIncrementer,但将日期设为非标识参数。这样,run.id 参数将有助于识别作业实例(因此每次运行都会有一个新实例),但 date 参数不会有助于识别作业实例。非识别作业参数应以“-”为前缀(参见javadoc of the DefaultJobParametersConverter)。

    希望这会有所帮助。

    【讨论】:

    • 感谢您的回复...我有相同的结果...我尝试了 java -jar -Dspring.profiles.active=gus /applications/botbit-batch/botbit-batch- 1.0.0.jar --spring.batch.job.names=persistCustomerSuccessMetrics -date=2018-01-20 并在我的阅读器中放置一个 logger.info ,但它总是显示第一个执行日期。也许我以错误的方式传递参数
    • 您需要使用像--date=2018-01-20这样的双破折号,因为参数转换器将删除一个破折号(这与Spring Boot如何处理参数有关)。这样,参数date 最终将成为-date=2018-01-20,并将被视为非标识。如果这有帮助,请告诉我。
    • 日志显示[{-date=2018-01-20, run.id=2, ....],spring-batch 没有将该参数作为识别参数......现在的问题是他的值,始终为空。我正在使用@Value("#{jobParameters[date]}" 注入此参数,我在前面的表达式中尝试过'[-date]',但它也不起作用,抛出异常。我很想使用 -D 系统参数:)
    • 更新:我已将表达式更改为@Value("#{jobParameters['-date']}",现在情况正好相反。我可以在我的阅读器中注入参数,但它需要第一次执行的值
    • The logs shows [{-date=2018-01-20, run.id=2, ....] the parameter is not taken by spring-batch as an identifying parameter 但这就是我们想要的,对吧?我们希望run.id 是可识别的,而date 是不可识别的。对吗?
    【解决方案3】:

    问题在于 getNexJobParameters 是如何工作的。它获取作业的最后一个(!)实例的最后一次执行的 JobParameters,并将其作为 JobParameterIncrementer 的输入。这种方式通常新实例将继承某种意义上任意作业实例的参数。这显然也将包括非识别参数。 您可以在命令行上显式覆盖旧参数值。

    【讨论】:

      猜你喜欢
      • 2017-11-09
      • 1970-01-01
      • 2012-06-12
      • 1970-01-01
      • 1970-01-01
      • 2020-06-03
      • 2019-01-05
      • 2021-06-25
      • 2022-12-09
      相关资源
      最近更新 更多