WEB/Spring Batch

스프링 배치 실행 - Job

Tony Lim 2023. 2. 23. 19:36
728x90

배치초기화 설정

1. JobLauncherApplicationRunner

- Spring Batch 작업을 시작하는 ApplicationRunner로서 BatchAutoConfiguration에서 생성

- ApplicationRunner의 구현체임으로 spring boot가 정상적으로 구동되자마자 실행됨

- 기본적으로 빈으로 등록된 모든 Job들을 실행시킨다.

 

2. BatchProperties

- Spring Batch의 환경설정 클래스

- Job 이름 , 스키 초기화 설정, 테이블의 prefix 등을 설정할 수 있다.

- application.properties or application.yml 파일에 설정함

spring
  batch:
    jdbc:
      initialize-schema: always

 

3. Job 실행 옵션

- 지정한 Batch Job만 실행하도록 할 수 있음

- spring.batch.job.names: ${job.name:None}

- 앱 실행시 Program argument 로 job이름을 입력한다.

ㅡ job.name=HelloJobs,SimpleJobs  (여러개면 comma로 구분함)

JobLauncehrApplicationRunner#executeLocalJobs에서 인자로 주어진 job.name을 일일이 비교해서 일치하는 Job만 실행시켜준다.

 


JobBuilderFactory

 

1. 스프링 배치는 Job과 Step 을 쉽게 생성 및 설정할 수 있도록 util 성격의 빌더 클래스들을 제공함
Job을 직접생성하지는 않음

 

2. JobBuilderFactory

- JobBuilder를 생성하는 팩토리 클래스로서 get(String name) 메서드 제공

- jobBuilderFactory.get("jobName")

ㅡ "jobName"은 스프링 배치가 Job을 실행시킬 때 참조하는 이름 = application.yml에 설정하는
spring.batch.name= simpleJob1

 

3. JobBuilder

- Job을 구성하는 설정 조건에 따라 두개의 하위 빌더 클래스를 생성하고 실제 Job 생성을 위임한다.

- SimpleJobBuilder

ㅡ SimpleJob을 생성하는 Builder 클래스

ㅡ Job 실행과 관련된 여러 설정 API를 제공한다.

- FlowJobBuilder

ㅡ FlowJob을 생성하는 Builder 클래스

ㅡ 내부적으로 FlowBuilder를 반환함으로써 Flow 실행과 관련된 여러 설정 API를 제공한다.

 

 결론적으로는 SimpleJob 을 생성할것이냐 FlowJob을 생성할것이냐의 차이다.

 

JobBuilder 가 생성되는 클래스간의 계층 및 구조를 명확하게 이해하면 Job Configuration 을 구성할 때 많은 도움이 된다.

JobRepository는 빌더 클래스를 통해 Job 객체에 전달되어 메타데이터를 기록하는데 사용된다.

 


SimpleJob - 개념 및 API 소개

 

1. 기본개념

- SimpleJob 은 Step 을 실행시키는 Job구현체로서 SimpleJobBuilder에 의해 생성된다.

- 여러단계의 Step으로 구성할 수 있으며 Step 을 순차적으로 실행시킨다.

- 모든 Step의 실행이 성공적으로 완료되어야 Job이 성공적으로 완료 된다.

- 맨 마지막에 실행한 Step 의 BatchStatus 가 Job의 최종 BatchStatus가 된다.

JobBuilderHelper의 CommonProperties에서 들고 있는 여러 설정값을 SimpleJob에 set하게 된다.

@Bean
public Job batchJob() {
    return this.jobBuilderFactory.get("batchJob")
            .incrementer(new RunIdIncrementer())
            .validator(new JobParametersValidator() {
                @Override
                public void validate(JobParameters parameters) throws JobParametersInvalidException {

                }
            })
            .preventRestart()
            .start(step1())
            .next(step2())
            .next(step3())
            .build();
}

이런식으로 SimpleJob의 필드값들을 채워줄수 있다. 채워지는 시점이 위의JobBuilderHelper#enhance 메소드에서 setter로 세팅이 된다.


SimpleJob - validator()

 

1. 기본개념

- Job실행에 꼭 필요한 파라미터를 검증하는 용도

- DefaultJobParametersValidator 구현체를 지원하며 , 좀 더 복잡한 제약 조건이 있다면 인터페이스를 직접 구현할 수 있음

- JobParameters값을 매개 변수로 받아서 검증하게 된다.

requiredKey에 포함된 key가 JobParameter에 존재하지 않으면 Exception을 던지고 Job을 수행하지 않는다.

public class CustomJobParametersValidator implements JobParametersValidator {

    @Override
    public void validate(JobParameters jobParameters) throws JobParametersInvalidException {

        if (jobParameters.getString("name") == null) {

            throw new JobParametersInvalidException("name parameter is not found.");

        }
    }
}
    @Bean
    public Job batchJob() {
        return this.jobBuilderFactory.get("batchJob")
                .validator(new CustomJobParametersValidator())
//                .validator(new DefaultJobParametersValidator(new String[]{"name"},new String[]{"year"}))
                .start(step1())
                .next(step2())
                .next(step3())
                .build();
    }

이런식으로 custom validator를 만들어서 검증하고 싶은 로직을 추가할 수 있다.

아예 Job을 수행하지 않기때문에 JobInstance , JobExecution 등등이 전혀 생성되지도 않는다. 검증은 제일처음 수행되는것이기 때문이다.


SimpleJob - preventRestart()

 

1. 기본개념

- Job의 재시작 여부를 결정

- 기본 값은 true이며 false로 설정시 = 이 job은 재 시작을 지원하지 않는다 라는 의미

- Job이 실패해도 재 시작이 안되며 Job을 재시작하려고 하면 JobRestartException 이 발생

- 재 시작과 관련 있는 기능으로 Job을 처음 실행하는것 과는 아무런 상관 없음

@Bean
public Job batchJob() {
    return this.jobBuilderFactory.get("batchJob")
            .start(step1())
            .next(step2())
            .next(step3())
            .preventRestart()
            .build();
}

별도의 설정없이 preventRestart를 호출하는것만으로도 재시작을 방지하게 동작한다.
AbstractJob의 restartable = true를 false로 바꿔주는 역할이다. 

@Override
public JobExecution run(final Job job, final JobParameters jobParameters)
      throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException,
      JobParametersInvalidException {

   Assert.notNull(job, "The Job must not be null.");
   Assert.notNull(jobParameters, "The JobParameters must not be null.");

   final JobExecution jobExecution;
   JobExecution lastExecution = jobRepository.getLastJobExecution(job.getName(), jobParameters);
   if (lastExecution != null) {
      if (!job.isRestartable()) {
         throw new JobRestartException("JobInstance already exists and is not restartable");
      }

SimpleJobLauncher에서 현재 job에 해당되는 가장 최근 JobExecution을 가지고 왔을때 preventStart를 호출한 상태였다면 Execption을 던지게 되는것이다.

 


SimpleJob - incrementer()

 

1. 기본개념

- JobParameters 에서 필요한 값을 증가시켜 다음에 사용될 JobParameters 오브젝트를 리턴

- 기존의 JobParameter 변경없이 Job을 여러 번 시작하고자 할 때

- RunIdIncrementer 구현체를 지원하며 인터페이스를 직접 구현할 수 있음

public class CustomJobParametersIncrementer implements JobParametersIncrementer {

    static final SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd-hhmmss");

    public JobParameters getNext(JobParameters parameters) {

        String id = format.format(new Date());

        return new JobParametersBuilder().addString("run.id", id).toJobParameters();
    }
}
    @Bean
    public Job batchJob() {
        return this.jobBuilderFactory.get("batchJob")
//                .incrementer(new RunIdIncrementer())
                .incrementer(new CustomJobParametersIncrementer())
                .start(step1())
                .next(step2())
                .next(step3())
                .build();
    }

어떻게 다른 JobParameter를 매 실행마다 제공할것인지 구현할 수 있다.

JobInstance = Job + JobParameters 임으로 계속 새 객체가 생성된다.

Incrementer는 다른 JobParameters의 값은 유지하고 싶고 계속 반복 실행을 해야 될때 유용하게 사용될 수 있다.

 


SimpleJob 아키텍처

JobInstance = Job + JobParameter

JobInstance  : JobExecution = 1 : N

JobListener 를 통해 실행 전후로 처리할 비지니스 콜백을 장착할 수 있음

JobExecution은 마지막 Step의 state와 동일하게 된다. 즉 모든 step이 다 성공해야 성공, 하나라도 실패하면 실패.

 

 

 

728x90

'WEB > Spring Batch' 카테고리의 다른 글

스프링 배치 실행 - Flow  (0) 2023.03.03
스프링 배치 실행 - Step  (0) 2023.02.28
스프링 배치 도메인 이해  (0) 2023.02.17
스프링 배치 소개 + 시작  (0) 2023.02.16
java brains) Spring Batch  (0) 2021.05.29