2016-12-28 5 views
0

Я разрабатываю Spring с использованием Spring Boot.Как запустить Spring Batch Jobs в определенном порядке (Spring Boot)?

Я с минимальной конфигурацией, предоставленной Spring Boot, и определл некоторые задания (без конфигурации XML вообще). Но когда я запускаю приложение,

SpringApplication.run(App.class, args); 

Работы выполняются последовательно в произвольном порядке.

Я определения рабочих мест таким образом, в @Configuration аннотированных классов, Spring сделает все остальное:

@Bean 
public Job requestTickets() { 
    return jobBuilderFactory.get(Config.JOB_REQUEST_TICKETS) 
      .start(stepRequestTickets()) 
      .build(); 
} 

Как я могу проинструктировать рамки для выполнения заданий в определенном порядке?

EDIT: Может ли это предупреждение дать подсказку? (Возможно, нечего делать)

2016-12-29 17:45:33.320 WARN 3528 --- [main] o.s.b.c.c.a.DefaultBatchConfigurer: No datasource was provided...using a Map based JobRepository 
+0

Итак, у вас есть одна работа с несколькими шагами или несколькими заданиями? Похоже, у вас есть только одна работа. Вы имеете в виду ** шаги **, когда вы говорите ** задания **? Показать код для 'stepRequestTickets()'. –

+0

У меня много JOBS. Я хочу запускать задания последовательно в фиксированном порядке, но не могу найти способ заказа заданий. Это всего лишь фрагмент того, как я определяю работу. –

ответ

2

1.You первый отключить автоматический запуск задания, указав spring.batch.job.enabled=false в application.properties

2.In ваш главный класс, сделать - ApplicationContext ctx = SpringApplication.run(SpringBatchMain.class, args); предполагая ваш основной класс называется - SpringBatchMain.java.

Это инициализирует контекст без каких-либо заданий.

контекст 3.Once инициализируется, либо вы можете сделать - JobLauncher jobLauncher = (JobLauncher) ctx.getBean("jobLauncher"); или сделать Autowired для этого JobLauncher фасоли в главном классе и запускать конкретные задания последовательно в конкретном последовательном порядке путем вызова, jobLauncher.run(job, jobParameters).

Вы можете получить конкретные job примеров из контекста инициализируется на шаге 2.

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

4.Этот вышеописанный метод работает до тех пор, пока ваш JobLauncher настроен на синхронность, т. Е. Основной поток ожидает завершения вызова jobLauncher.run(), и это поведение по умолчанию для jobLauncher.

Если вы определили свой jobLauncher для использования AsyncTaskExecutor, то задания будут запускаться параллельно, и последовательный заказ не будет поддерживаться.

Надеюсь, это поможет!

EDIT:

Я экспериментировал с @Order аннотацию, как отметил Стефан Nicoll и это, кажется, только помочь в создании упорядоченного набора рабочих мест и что вы можете перемещаться и запускать задания в таком порядке.

Это ниже компонента дает мне работу в указанном порядке,

@Component 
public class MyJobs { 
    @Autowired 
    private List<Job> jobs; 

    public List<Job> getJobs() { 
     return jobs; 
    } 
} 

и я могу сделать, MyJobs myJobs = (MyJobs) ctx.getBean("myJobs"); в главном классе при условии боба определяется,

@Bean 
    public MyJobs myJobs() { 
     return new MyJobs(); 
    } 

я могу перебирать myJobs и рабочие места запуска в указанном порядке, указанном аннотацией @Order.

+0

Все получилось! Но дополнительный вопрос: где вы поместите свой '@ Bean'code? Если я поместил его в метод 'main', он отлично работает. Но если я поместил его внутри '@ Component', я получаю ошибку Spring:' BeanDefinitionStoreException: Неверное определение bean с именем 'myJobs', определенным в ресурсе пути к классу [.../MyJobs.class]: ссылка на заводскую станцию ​​возвращается к то же определение бобов' –

+0

Я выяснил, что определение '@ Bean' не требуется. Я думаю, '@ Component' уже создает необходимый компонент. –

+0

Я имею в виду, вам нужно пойти с Орденом, если у вас слишком много рабочих мест, и его трудно справиться. Для одной или двух заданий вы можете просто запустить ручной запуск задания без использования аннотации Order. –

1

Закажите.

@Bean 
@Order(42) 
public Job requestTickets() { 
    return jobBuilderFactory.get(Config.JOB_REQUEST_TICKETS) 
      .start(stepRequestTickets()) 
      .build(); 
} 

Для получения более подробной информации см. javadoc of @Order.

+0

'@ Order' не получилось. Я вставил аннотацию точно так же, как вы предлагаете с помощью '@Order (1)', '@Order (2)', '@Order (3)' на мои 3 задания, но они выполняются, как и раньше. –

+0

Тогда вы не используете пусковую установку. Или вы используете очень старую версию Spring Boot. –

+0

@StephaneNicoll: Что вы подразумеваете под ** Тогда вы не используете пусковую установку **. 'jobLauncher.run (job, jobParameters)' запускает определенные задания, так что это похоже на ручной порядок. Я тестировал @Order и не работал, как описано в вашем ответе. Я использую Spring Boot 1.4.0. Не уверен, что OP тоже имеет обновление? –

0

Если ваше одно задание зависит от второго и так далее, тогда сделайте что-нибудь подобное.

@Configuration 
@EnableBatchProcessing 
@Import(DataSourceConfiguration.class) 
public class AppConfig { 

    @Autowired 
    private JobBuilderFactory jobs; 

    @Autowired 
    private StepBuilderFactory steps; 

    @Bean 
    public Job job(@Qualifier("step1") Step step1, @Qualifier("step2") Step step2) { 
     return jobs.get("myJob").start(step1).next(step2).build(); 
    } 

    @Bean 
    protected Step step1(ItemReader<Person> reader, ItemProcessor<Person, Person> processor, ItemWriter<Person> writer) { 
     return steps.get("step1") 
      .<Person, Person> chunk(10) 
      .reader(reader) 
      .processor(processor) 
      .writer(writer) 
      .build(); 
    } 

    @Bean 
    protected Step step2(Tasklet tasklet) { 
     return steps.get("step2") 
      .tasklet(tasklet) 
      .build(); 
    } 
} 
+0

. Я думаю, что вы говорите о порядке заказа, но мне нужно запустить JOBS в определенном порядок, поскольку 'Job_n' зависит от' Job_n-1'. –

0

У меня недостаточно комментариев для комментариев. Но пытались ли вы просто вручную запускать свои задания в том порядке, в котором вы хотите?

Вам необходимо установить spring.batch.job.enabled = false в ваших приложениях.properties, чтобы ваши задания не запускались автоматически.

Затем просто используйте пусковую установку для запуска своих заданий в том порядке, в котором вы хотите.

@RunWith(SpringRunner.class) 
@SpringBootTest(classes = { TestConfiguration.class, TestDataSourceConfiguration.class, TestBatchConfig.class }) 
public class JobOrderTest { 

    @Autowired 
    JobLauncher jobLauncher; 

    @Mock 
    Job firstJob; 

    @Mock 
    Job secondJob; 

    @Mock 
    Job thirdJob; 

    @Mock 
    JobParametersValidator jobParametersValidator; 

    @Test 
    public void jobInOrderTest() throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException { 

     when(firstJob.getName()).thenReturn(UUID.randomUUID().toString()); 
     when(secondJob.getName()).thenReturn(UUID.randomUUID().toString()); 
     when(thirdJob.getName()).thenReturn(UUID.randomUUID().toString()); 
     when(firstJob.getJobParametersValidator()).thenReturn(jobParametersValidator); 
     when(secondJob.getJobParametersValidator()).thenReturn(jobParametersValidator); 
     when(thirdJob.getJobParametersValidator()).thenReturn(jobParametersValidator); 

     jobLauncher.run(firstJob, new JobParameters()); 
     jobLauncher.run(secondJob, new JobParameters()); 
     jobLauncher.run(thirdJob, new JobParameters()); 
    } 

} 

Вот выход

2016-12-30 09:48:36.457 INFO 144860 --- [cTaskExecutor-1] o.s.b.c.l.support.SimpleJobLauncher  : Job: [firstJob] launched with the following parameters: ... 
2016-12-30 09:48:36.457 INFO 144860 --- [cTaskExecutor-1] o.s.b.c.l.support.SimpleJobLauncher  : Job: [firstJob] completed with the following parameters: ... 
2016-12-30 09:48:36.478 INFO 144860 --- [cTaskExecutor-2] o.s.b.c.l.support.SimpleJobLauncher  : Job: [secondJob] launched with the following parameters: ... 
2016-12-30 09:48:36.478 INFO 144860 --- [cTaskExecutor-2] o.s.b.c.l.support.SimpleJobLauncher  : Job: [secondJob] completed with the following parameters: ... 
2016-12-30 09:48:36.508 INFO 144860 --- [cTaskExecutor-3] o.s.b.c.l.support.SimpleJobLauncher  : Job: [thirdJob] launched with the following parameters: ... 
2016-12-30 09:48:36.508 INFO 144860 --- [cTaskExecutor-3] o.s.b.c.l.support.SimpleJobLauncher  : Job: [thirdJob] completed with the following parameters: ... 
Смежные вопросы