2013-03-17 5 views
6

Как перезапустить рабочие места после сбоя JVM?Spring Batch после аварии JVM

У меня было много рабочих заданий, реализованных в Spring Batch framework, когда моя JVM разбилась или система потерпела неудачу. Как перезапустить эти задания после сбоя?

ответ

6

В принципе, вы можете сделать следующее:

  1. Конфигурирование JobExplorer завод боб в контексте вашего приложения:

  2. настроить JobOperator боба в вашем контексте applictaion

  3. Запрос jobExplorer для отдельных наименований: jobExplorer.getJobNames()

  4. Для каждого задания из стадии (3) запрос к jobExplorer для незавершенных работ: jobExplorer.findRunningJobExecutions(String jobName)

  5. Для каждого JobExecution стадии (4) вызова: jobOperator.restart(jobExecution.getJobId())

  6. Обязательно позовите эту процедуру во время процесса загрузки, прежде, чем любая другая работа запускаются

Технически это можно объединить шаги 3 + 4 что-то вроде findRunningJobExecutions() переопределива JobExecutionDao, но в настоящее время API не поддерживает его.

Для помощи в вышеупомянутой конфигурации Spring бина, проконсультироваться с reference documentation

+0

Пожалуйста [см мой вопрос ] (http://stackoverflow.com/questions/40990935/resume-a-spring-batch-job-from-last-processed-point). Я пытаюсь обрабатывать тот же сценарий, работа начинается, но уже обработанные куски не учитываются автоматически. –

+0

Это работает на весеннем ботинке? Я имею в виду, можем ли мы обрабатывать приложение Spring boot, исключение, а также сбой и повторный запуск? – Kenji

2

Вот полное решение, чтобы перезапустить работу после JVM аварии.

  1. Сделать Перезапускаемые работу, делая restarable = "истинный"

идентификатор задания = "JobName" XMLNS = "http://www.springframework.org/schema/batch" Перезапускаемые = "true"

2. Код перезапускать работу

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(); 
     } 
    } 
} 

3.

<bean id="jobRepository" class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean" p:dataSource-ref="dataSource" p:transactionManager-ref="transactionManager" p:lobHandler-ref="oracleLobHandler"/> 

<bean id="oracleLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler"/> 


<bean id="jobExplorer" class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean" p:dataSource-ref="dataSource" /> 

<bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.MapJobRegistry" /> 

<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher"> 
     <property name="jobRepository" ref="jobRepository" /> 
     <property name="taskExecutor" ref="jobLauncherTaskExecutor" /> 
</bean> 
<task:executor id="jobLauncherTaskExecutor" pool-size="6" rejection-policy="ABORT" /> 

<bean id="jobOperator" class="org.springframework.batch.core.launch.support.SimpleJobOperator" p:jobLauncher-ref="jobLauncher" p:jobExplorer-re`enter code here`f="jobExplorer" p:jobRepository-ref="jobRepository" p:jobRegistry-ref="jobRegistry"/> 
4

Вы должны отметить "Running" рабочих мест, не удалось перед перезапуском их, как это:

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); 
     } 
    } 
}