복붙노트

[SPRING] Spring Batch Job을 특정 순서 (Spring Boot)로 실행하는 방법?

SPRING

Spring Batch Job을 특정 순서 (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();
}

특정 순서로 작업을 실행하도록 프레임 워크에 지시하려면 어떻게합니까?

편집 :이 경고 힌트를 줄 수 있을까요? (어쩌면 아무것도 할 수 없다)

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

해결법

  1. ==============================

    1.1. 먼저 application.properties에서 spring.batch.job.enabled = false를 지정하여 자동 작업 시작을 비활성화합니다.

    1. 먼저 application.properties에서 spring.batch.job.enabled = false를 지정하여 자동 작업 시작을 비활성화합니다.

    2. 메인 클래스에서, - ApplicationContext ctx = SpringApplication.run (SpringBatchMain.class, args); 기본 클래스가 SpringBatchMain.java라고 가정합니다.

    이렇게하면 작업을 시작하지 않고 컨텍스트가 초기화됩니다.

    컨텍스트가 초기화되면, 다음 중 하나를 수행 할 수 있습니다. - JobLauncher jobLauncher = (JobLauncher) ctx.getBean ( "jobLauncher"); 또는 주 클래스에있는이 JobLauncher 빈에 대해 Autowired를 수행하고 jobLauncher.run (job, jobParameters)을 호출하여 특정 순차 순서로 특정 작업을 순차적으로 실행하십시오.

    2 단계에서 초기화 된 컨텍스트에서 특정 작업 인스턴스를 가져올 수 있습니다.

    언제든지 주문한 콜렉션을 사용하여 그곳에 작업을 배치하고 콜렉션을 반복하여 작업을 시작할 수 있습니다.

    4. 위의 기술은 JobLauncher가 동기로 구성되어있는 한 작동합니다. 즉, 주 스레드는 jobLauncher.run () 호출이 완료 될 때까지 대기하며 이는 jobLauncher의 기본 동작입니다.

    AsyncTaskExecutor를 사용하도록 jobLauncher를 정의한 경우 작업이 병렬로 시작되며 순차 정렬은 유지되지 않습니다.

    희망이 도움이 !!

    편집하다:

    Stephane Nicoll이 지적한 @Order 주석을 실험하고 있었으며 Ordered 작업 컬렉션을 만드는 데만 도움이 될 것입니다. 그리고 순서대로 작업을 반복하고 시작할 수 있습니다.

    아래의 구성 요소는 지정된 Order로 작업을 제공합니다.

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

    @Order 주석에 지정된대로 myJobs를 반복하고 그 순서대로 작업을 시작할 수 있습니다.

  2. ==============================

    2.주문 해.

    주문 해.

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

    자세한 내용은 @Order의 javadoc을 참조하십시오.

  3. ==============================

    3.다음은 그 해결책의 실례입니다.

    다음은 그 해결책의 실례입니다.

    이것은 이상하게 보입니다. 우리가 프로세스를 해킹하고있는 것처럼 보입니다.

    spring.batch.job.enabled = false

    @SpringBootApplication
    @EnableBatchProcessing
    public class MyApplication {
    
        public static void main(String[] args)
                throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException {
    
            ConfigurableApplicationContext ctx = SpringApplication.run(MyApplication.class, args);
            JobLauncher jobLauncher = (JobLauncher) ctx.getBean("jobLauncher");
            Job job1= (Job) ctx.getBean("job1");
            Job job2= (Job) ctx.getBean("job2");
            jobLauncher.run(job1,new JobParameters());
            jobLauncher.run(job2,new JobParameters());
        }
    
    }
    
  4. ==============================

    4.나는 의견을 말할 충분한 담당자가 없습니다. 하지만 원하는 순서대로 수동으로 작업을 시작하려 했습니까?

    나는 의견을 말할 충분한 담당자가 없습니다. 하지만 원하는 순서대로 수동으로 작업을 시작하려 했습니까?

    application.properties에 spring.batch.job.enabled = false를 설정하여 작업이 자동으로 실행되지 않도록해야합니다.

    그런 다음 런처를 사용하여 원하는 순서대로 작업을 시작하십시오.

    @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: ...
    
  5. ==============================

    5.만약 당신의 한 직업이 두 번째 직업 등에 의존한다면, 이와 같은 일을하십시오.

    만약 당신의 한 직업이 두 번째 직업 등에 의존한다면, 이와 같은 일을하십시오.

    @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();
        }
    }
    
  6. from https://stackoverflow.com/questions/41364220/how-to-run-spring-batch-jobs-in-certain-order-spring-boot by cc-by-sa and MIT license