2016-08-02 2 views
5

У меня есть Spring загрузки Batch приложения:Как График Spring загрузки Batch Application

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 

@SpringBootApplication 
public class LoadApplication { 

    public static void main(String[] args) { 
     SpringApplication.run(LoadApplication.class, args); 
    } 
} 

В в @Configuration классе также с аннотацией @EnableBatchProcessing, я следующая пакетное задание боб определено:

@Bean 
public Job loadJob(JobBuilderFactory jobs, Step stepLoadFile, Step stepArchiveFile) { 
    return jobs.get("loadJob") 
      .incrementer(new RunIdIncrementer()) 
      .start(stepLoadFile) 
      .next(stepArchiveFile) 
      .build(); 
} 

Загрузочный файл stepLoadFile читает плоский файл (см. Ниже) и записывает данные файла в базу данных. stepArchiveFile затем перемещает файл в другой каталог.

Обычно задание должно выполняться один раз в день (вторник - суббота) в указанное время. Однако, если плоский файл не найден, задание не работает, и его необходимо перезапустить каждые 30 минут, пока он не завершится, или не будет достигнут максимальное количество попыток (например, 5). После успешного повторного запуска задание не должно запускаться снова до следующего нормального времени работы. Кроме того, система должна в идеале предотвращать параллельные прогоны одной и той же работы. Как все это можно сделать?

Примечание: повторное воспроизведение не требуется, чтобы выполнить сбой предыдущей работы. Это связано с тем, что размер блока больше, чем количество элементов в файле.

Я попробовал это в моем @Configuration классе (Примечание: Я также добавил @EnableRetry конфигурации и основной класс):

@Bean 
public ItemReader<Test> reader(LineMapper<Test> lineMapper, ApplicationProperties properties) { 
    FlatFileItemReader<Test> flatFileItemReader = new FlatFileItemReader<Test>() { 
     @Override 
     @Retryable(value = {ItemStreamException.class}, maxAttempts=5) 
     public void open(ExecutionContext executionContext) throws ItemStreamException { 
      super.open(executionContext); 
     } 

     @Override 
     @Retryable(maxAttempts=5) 
     public Holding read() throws UnexpectedInputException, ParseException, Exception { 
      return super.read(); 
     } 

    }; 
    flatFileItemReader.setResource(new FileSystemResource(properties.getLoadFile())); 
    flatFileItemReader.setLineMapper(lineMapper); 
    return flatFileItemReader; 
} 

ItemStreamException брошено и выход из приложения без повтором.

ответ

6

Вы можете запланировать путем добавления ниже компонента в классе LoadApplication

@Component 
@EnableScheduling 
class ScheduledTasks { 
@Autowired 
JobLauncher jobLauncher; 

@Autowired 
Job job; 

/**The pattern is a list of six single space-separated fields: 
* representing second, minute, hour, day, month, weekday. 
* Month and weekday names can be given as the first three letters of the English names. 
* Example patterns: 

    "0 0 * * * *" = the top of every hour of every day.* 
    "*\/10 * * * * *" = every ten seconds. Remove 2nd character, it is escape 
    "0 0 8-10 * * *" = 8, 9 and 10 o'clock of every day. 
    "0 0/30 8-10 * * *" = 8:00, 8:30, 9:00, 9:30 and 10 o'clock every day. 
    "0 0 9-17 * * MON-FRI" = on the hour nine-to-five weekdays 
    "0 0 0 25 12 ?" = every Christmas Day at midnight 

*/ 
@Scheduled(cron = "0 0/30 * * * TUE-SAT") 
public void runJob() throws Exception { 
    jobLauncher.run(job, new JobParameters()); 
} 
} 

Для повторение не удалось шаги, которые вы, возможно, придется настроить его на работу шаг сам
<chunk reader="itemReader" writer="itemWriter" commit-interval="2" retry-limit="5"> <retryable-exception-classes> <include class="java.io.FileNotFoundException"/> </retryable-exception-classes> </chunk>

Кроме того, если вы храните пружинный пакет метаданных на диске, а не в памяти, весенняя партия не будет запускать ту же работу снова.

+0

Спасибо за ответ. К сожалению, однако, я не думаю, что это полностью выполняет то, что мне нужно. Работа должна выполняться обычно один раз в день. В '@ Scheduled', вы запускаете его каждые 30 минут. Когда происходит сбой задания, мне нужно его повторять каждые 30 минут, пока он не удастся. С 'retry-limit', я думаю, что он будет немедленно повторять попытку, а не ждать 30 минут. Я также считаю, что 'retry-limit' находится на уровне позиции, а не на уровне работы. Пожалуйста, поправьте меня, если я ошибаюсь в любом из этих пунктов. – James

0

Используйте условный поток в объявлении шага.
<step id="readWrite"> <tasklet>(...)</tasklet> <next on="FAILED" to="scheduleNext" /> </step> <step id="scheduleNext"> <tasklet ref="schedulerTasklet"> </step> <bean id="schedulerTasklet" class="SchedulerTasklet"/>

и в расписании SchedulerTasklet следующем запуске:

public class SchedulerTasklet implements Tasklet { 
    @Autowired private TaskScheduler taskScheduler; 
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { 
     Runnable task = new Runnable() { 
      public void run() { 
       run your job here 
      } 
     }; 
     taskScheduler.schedule(task, delay); 
     return RepeatStatus.FINISHED; 
    } 
}