Spring boot Spring批处理在群集环境中正确重新启动未完成的作业

Spring boot Spring批处理在群集环境中正确重新启动未完成的作业,spring-boot,spring-batch,high-availability,Spring Boot,Spring Batch,High Availability,我使用以下逻辑在单节点Spring批处理应用程序上重新启动未完成的作业: public void restartUncompletedJobs() { try { jobRegistry.register(new ReferenceJobFactory(documetPipelineJob)); List<String> jobs = jobExplorer.getJobNames(); for (String job :

我使用以下逻辑在单节点Spring批处理应用程序上重新启动未完成的作业:

public void restartUncompletedJobs() {

    try {
        jobRegistry.register(new ReferenceJobFactory(documetPipelineJob));

        List<String> jobs = jobExplorer.getJobNames();
        for (String job : jobs) {
            Set<JobExecution> runningJobs = jobExplorer.findRunningJobExecutions(job);

            for (JobExecution runningJob : runningJobs) {
                runningJob.setStatus(BatchStatus.FAILED);
                runningJob.setEndTime(new Date());
                jobRepository.update(runningJob);
                jobOperator.restart(runningJob.getId());
            }
        }
    } catch (Exception e) {
        LOGGER.error(e.getMessage(), e);
    }
}

我有一个关于#2.1的问题-Spring Batch是否会在应用程序重新启动后自动重新启动未完成的作业并执行运行,或者我是否需要执行手动操作才能执行此操作?

您的逻辑不是重新启动未完成的作业。您的逻辑是获取当前正在运行的作业执行,将其状态设置为
失败
,然后重新启动它们。您的逻辑不应该找到正在运行的执行,它应该查找当前未运行的执行,尤其是失败的执行,然后重新启动它们

如何正确地重新启动失败的作业,并防止像jobInstance2这样的作业也将重新启动的情况

在伪代码中,您需要做的是:

  • 使用
    JobOperator\getJobInstances
  • 对于每个实例,使用
    JobOperator\getExecutions
    检查是否有正在运行的执行

    2.1如果有正在运行的执行,则移动到下一个实例(以便让执行成功或失败地完成)

    2.2如果当前没有正在运行的执行,请检查上次执行的状态,如果执行失败,请使用
    JobOperator\restart
    重新启动

  • 在您的场景中:

    • jobInstance1
      应在步骤2.2中重新启动
    • jobInstance2
      应该在步骤2.1中进行过滤,因为它在节点2上有一个正在运行的执行

    谢谢您的回答!我有一个问题-
    JobOperator#getExecutions
    是否会区分当前正在运行的执行和数据库中处于运行状态但由于应用程序异常终止而未立即运行的执行?否,
    JobOperator#getExecutions
    返回所有执行,无论其状态如何。还有另一个名为
    JobOperator#getRunningExecutions
    的方法返回正在运行的执行。获得所有执行后,您可以检查它们的状态(并筛选案例中正在运行的执行)。请参阅:
    Get the job instances of your job with JobOperator#getJobInstances
    
    For each instance, check if there is a running execution using JobOperator#getExecutions.
    
    2.1 If there is a running execution, move to next instance (in order to let the execution finish either successfully or with a failure)
    
    2.2 If there is no currently running execution, check the status of the last execution and restart it if failed using JobOperator#restart.