JVM崩溃后的Spring批处理

JVM崩溃后的Spring批处理,spring,spring-batch,Spring,Spring Batch,JVM崩溃后如何重新启动作业 当我的JVM崩溃或系统失败时,我正在运行许多在SpringBatch框架中实现的作业。失败后如何重新启动这些作业?基本上,您可以执行以下操作: 在应用程序上下文中配置JobExplorerFactorybean: 在应用程序上下文中配置JobOperatorbean 在jobExplorer中查询不同的作业名称:jobExplorer.getJobNames() 对于步骤(3)中的每个作业,请在jobExplorer中查询未完成的作业: jobExplorer.fi

JVM崩溃后如何重新启动作业


当我的JVM崩溃或系统失败时,我正在运行许多在SpringBatch框架中实现的作业。失败后如何重新启动这些作业?

基本上,您可以执行以下操作:

  • 在应用程序上下文中配置
    JobExplorer
    Factorybean:

  • 在应用程序上下文中配置
    JobOperator
    bean

  • 在jobExplorer中查询不同的作业名称:
    jobExplorer.getJobNames()

  • 对于步骤(3)中的每个作业,请在jobExplorer中查询未完成的作业:
    jobExplorer.findRunningJobExecutions(字符串jobName)

  • 对于步骤(4)中的每个
    JobExecution
    ,调用:
    jobOperator.restart(JobExecution.getJobId())

  • 确保在启动序列期间调用此过程,然后再启动任何其他作业

  • 从技术上讲,通过覆盖
    JobExecutionDao
    ,可以合并类似
    findRunningJobExecutions()
    的步骤3+4,但当前API不支持它


    要获得上述Springbean配置的帮助,请参阅

    ,这里是JVM崩溃后重新启动作业的完整解决方案

  • 通过设置restarable=“true”使作业可重新启动
  • 作业id=“jobName”xmlns=”http://www.springframework.org/schema/batch“restartable=“true”

    二,。重新启动作业的代码

    import java.util.Date;
    import java.util.List;
    import org.apache.commons.collections.CollectionUtils;
    import org.springframework.batch.core.BatchStatus;
    import org.springframework.batch.core.ExitStatus;
    import org.springframework.batch.core.JobExecution;
    import org.springframework.batch.core.JobInstance;
    import org.springframework.batch.core.explore.JobExplorer;
    import org.springframework.batch.core.launch.JobLauncher;
    import org.springframework.batch.core.launch.JobOperator;
    import org.springframework.batch.core.repository.JobRepository;
    import org.springframework.beans.factory.annotation.Autowired;
    
    public class ResartJob {
    
        @Autowired
        private JobExplorer jobExplorer;
        @Autowired
        JobRepository jobRepository;
        @Autowired
        private JobLauncher jobLauncher;
        @Autowired 
        JobOperator jobOperator;
    
        public void restart(){
            try {
                List<JobInstance> jobInstances = jobExplorer.getJobInstances("jobName",0,1);// this will get one latest job from the database
                if(CollectionUtils.isNotEmpty(jobInstances)){
                   JobInstance jobInstance =  jobInstances.get(0);
                   List<JobExecution> jobExecutions = jobExplorer.getJobExecutions(jobInstance);
                   if(CollectionUtils.isNotEmpty(jobExecutions)){
                       for(JobExecution execution: jobExecutions){
                           // If the job status is STARTED then update the status to FAILED and restart the job using JobOperator.java
                           if(execution.getStatus().equals(BatchStatus.STARTED)){ 
                               execution.setEndTime(new Date());
                               execution.setStatus(BatchStatus.FAILED);                               
                               execution.setExitStatus(ExitStatus.FAILED);                               
                               jobRepository.update(execution);
                               jobOperator.restart(execution.getId());
                           }
                       }
                   }
                }
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }
    }
    
    import java.util.Date;
    导入java.util.List;
    导入org.apache.commons.collections.CollectionUtils;
    导入org.springframework.batch.core.BatchStatus;
    导入org.springframework.batch.core.ExitStatus;
    导入org.springframework.batch.core.JobExecution;
    导入org.springframework.batch.core.JobInstance;
    导入org.springframework.batch.core.explore.JobExplorer;
    导入org.springframework.batch.core.launch.JobLauncher;
    导入org.springframework.batch.core.launch.JobOperator;
    导入org.springframework.batch.core.repository.JobRepository;
    导入org.springframework.beans.factory.annotation.Autowired;
    公共类转载作业{
    @自动连线
    私人JobExplorer;
    @自动连线
    作业库作业库;
    @自动连线
    私有JobLauncher JobLauncher;
    @自动连线
    作业操作员作业操作员;
    公共无效重新启动(){
    试一试{
    List jobInstances=jobExplorer.getJobInstances(“jobName”,0,1);//这将从数据库中获取一个最新作业
    if(CollectionUtils.isNotEmpty(jobInstances)){
    JobInstance JobInstance=jobInstances.get(0);
    List jobExecutions=jobExplorer.getJobExecutions(jobInstance);
    if(CollectionUtils.isNotEmpty(作业执行)){
    for(作业执行:作业执行){
    //如果作业状态为STARTED,则将状态更新为FAILED,并使用JobOperator.java重新启动作业
    如果(execution.getStatus().equals(BatchStatus.STARTED)){
    execution.setEndTime(新日期());
    execution.setStatus(BatchStatus.FAILED);
    execution.setExitStatus(ExitStatus.FAILED);
    jobRepository.update(执行);
    重新启动(execution.getId());
    }
    }
    }
    }
    }捕获(异常e1){
    e1.printStackTrace();
    }
    }
    }
    
    三,

    
    
    重新启动作业之前,需要将“正在运行”的作业标记为失败,如下所示:

    List<String> jobs = jobExplorer.getJobNames();
    for (String job : jobs) {
        Set<JobExecution> runningJobs = jobExplorer.findRunningJobExecutions(job);
    
        for (JobExecution runningJob : runningJobs) {
            try {
                runningJob.setStatus(BatchStatus.FAILED);
                runningJob.setEndTime(new Date());
                jobRepository.update(runningJob);
                jobOperator.restart(runningJob.getId());
            } catch (Exception e) {
                LOG.error(e.getMessage(), e);
            }
        }
    }
    
    List jobs=jobExplorer.getJobNames();
    for(字符串作业:作业){
    设置runningJobs=jobExplorer.findRunningJobExecutions(作业);
    for(作业执行运行作业:运行作业){
    试一试{
    runningJob.setStatus(BatchStatus.FAILED);
    runningJob.setEndTime(新日期());
    jobRepository.update(运行作业);
    重新启动(runningJob.getId());
    }捕获(例外e){
    LOG.error(e.getMessage(),e);
    }
    }
    }
    
    请。我正在尝试处理相同的场景,作业正在开始,但已经处理的块不会被自动考虑。这对Spring boot有效吗?我的意思是,我们是否能够处理SpringBoot应用程序出现异常并崩溃并再次运行?
    List<String> jobs = jobExplorer.getJobNames();
    for (String job : jobs) {
        Set<JobExecution> runningJobs = jobExplorer.findRunningJobExecutions(job);
    
        for (JobExecution runningJob : runningJobs) {
            try {
                runningJob.setStatus(BatchStatus.FAILED);
                runningJob.setEndTime(new Date());
                jobRepository.update(runningJob);
                jobOperator.restart(runningJob.getId());
            } catch (Exception e) {
                LOG.error(e.getMessage(), e);
            }
        }
    }