Spring Batch

sixhustle·2022년 6월 10일
0

Spring-Batch

목록 보기
1/1

Job

처음부터 끝까지 독립적으로 실행할 수 있는 고유하며, 순서가 지정된 여러 Step의 목록

  • 유일함 : Spring Bean과 동일한 방식이며 재사용 가능
  • 순서를 가진 여러 Step의 목록
  • 처음부터 끝까지 실행 가능 : 외부 의존성 없이 실행할 수 있다.
  • 독립적 : 각 배치 Job은 외부 의존성의 영향을 받지 않고 실행할 수 있어야 한다.

JobRunner

Job이름과 Parameter를 받아들여 Job을 실행시키는 역할이다.

종류설명
CommandLineJobRunnerscript를 이용하거나 cli에서 직접 Job을 실행할 때 사용
JobRegisteryBackgroundJobRunnerSpring내에서 Job을 실행한다면, 실행 가능한 Job을 가지고 있는 JobRegistry를 생성한다.
JobRegistry를 생성하는데 사용하는 Runner이다.
JobLauncherCOmmandLineRunnerSpring Boot는 ApplicationContext에 정의된 Job타입의 모든 빈을 기동 시에 실행

JobInstance

Job의 논리적 실행을 나타내고, 한 번 성공적으로 완료되면 다시 실행시킬 수 없다.

  • BatchJob이 실행되면, org.springframework.batch.core.JobInstance가 생성
  • JobInstance 상태는 BATCH_JOB_INSTANCE에 저장
  • JobInstance 식별은 BATCH_JOB_INSTANCEBATCH_JOB_EXECUTION_PARAMS 테이블을 사용

JobExecution

Job 실행의 실제 시도를 의미한다.

  • 생성된 JobExecution은 BATCH_JOB_EXECUTION 테이블에 저장
  • JobExecution의 상태는 BATCH_JOB_EXECUTION_CONTEXT 테이블에 저장
  • Job에서 오류가 발생하면, 위의 정보를 이용해 올바른 지점부터 다시 Job을 시작

Job 구성하기

p.96-98

JobParameter

JobInstance를 식별하는 값이다. 동일한 식별 파라미터로 동일한 잡을 두 번 이상 실행할 수 없다.


값 전달하기

# key: executionDate
# value: 2020/12/27
# value data type: date
java -jar demo.jar executionDate(date)=2020/12/27

# name은 식별자에서 제외
java -jar demo.jar executionDate(date)=2020/12/27 -name=Michael
  • 명령행으로 key=value 쌍을 전달한다.
  • 파라미터의 타입을 지정할 수 있고, 모두 소문자여야 한다.
  • String, Double, Long, Date 타입을 지원
  • 전달한 Parameter는 BATCH_JOB_EXECUTION_PARAMS 테이블에서 확인
  • 접두사 -를 사용하면, 식별자에서 제외된다.

접근하기

//	ChunkContext
@Bean
public Tasklet helloWorldTasklet() {
	return (contribution, chunkContext) -> {
    	String name (String) chunkContext.getStepContext()
        	.getJobParameters()
            .get("name");
        System.out.println(String.foramt("Hello, %s!", name));
        return RepeatStatus.FINISHED;
    };
}

//	Late Binding
@Bean
public Step step1() {
	return this.stepBuilderFactory.get("step1")
    			.tasklet(helloWorldTasklet(null))
                .build();
}

@Bean
public Tasklet helloWorldTasklet(
		@Value("#{jobParameters['name']}") String name) {

	return (contribution, chunkContext) -> {
    	String name (String) chunkContext.getStepContext()
        	.getJobParameters()
            .get("name");
        System.out.println(String.foramt("Hello, %s!", name));
        return RepeatStatus.FINISHED;
    };
}

//	@StepScope
@StepScope
@Bean
public Tasklet helloWorldTasklet(
		@Value("#{jobParameters['name']}") String name) {

	return (contribution, chunkContext) -> {
    	String name (String) chunkContext.getStepContext()
        	.getJobParameters()
            .get("name");
        System.out.println(String.foramt("Hello, %s!", name));
        return RepeatStatus.FINISHED;
    };
}
  • ChunkContext: JobParameter가 포함된 StepContext의 참조를 가진다.
  • Late Binding: 부투스트랩 시에 바인딩
  • @StepScope: 해당 어노테이션을 사용하면, 늦은 바인딩 기능을 사용할 수 있다.

유효성 검증

값이 예상한대로 유효한지 확인한다.

//	JobParametersValidator
//	JobPArametersInvalidException이 발생하지 않으면 유효성 검증은 통과
public class ParameterValidator implements JobParametersValidator {

	@Override
    public void validate(JobParameters parameters) throws JobParametersInvalidException {
    	String fileName = parameters.getString("fileName");
        
        if (!StringUtils.hasText(fileName)) {
        	throw new JobPArametersInvalidExcetion("fileName parameter is missing!");
        } else if (!StringUtils.endsWithIgnoreCase(fileName, "csv")) {
        	throw new JobParametersInvalidException("fileName parameter does not use the csv file extension");
        }
    }
}

//	DefaultJobParametersValidator
//	필수 파라미터가 누락없이 전달됐는지 확인하는 유효성 검증기
//	fileName과 name 외 다른 파라미터 변수가 전달되면 검증 실패
//	optionalKey가 구성되지 않으면, 필수키만 전달하면 검증 통과
@Bean
public JobParametersValidator validator() {
	DefaultJobParametersValidator validator = new DefaultJobParametersValidator();
    validator.setRequiredKeys(new String[] { "fileName" });
    validator.setOptionalKeys(new String[] { "name" });
    return validator;
}

//	CompositeJobParametersValidator
//	두 개의 유효성 검증기
@Bean
public CompositeJobParametersValidator validator() {
	CompositeJobParametersValidator validator = new CompositeJobParametersValidator();
    
    DefaultJobParametersValidator defaultJobParametersValidator = new DefaultJobParametersValidator(
    	new String[] { "fileName" },
        new String[] { "name" });

	defaultJobParametersValidator.afterPropertiesSet();
    
    validator.setValidators(
    	Arrays.asList(new ParameterValidator(), defaultJobParametersValidator);
    
	return validator;
}

@Bean
public Job job() {
	return this.jobBuilderFactory.get("basicJob")
    	.start(step1())
        .validator(validator())
        .build();
}

Incrementer: 값 증가 시키기

Incrementer: 파라미터를 고유하게 생성할 수 있는 인터페이스

//	RunIdIncrementer
//	프레임웤에서 제공하는 구현체
//	Validator에 run.id 값을 추가해야함
@Bean
public CompoisteJobParameterValidator validator() {
	...
    DefaultJobParametersValidator defaultJobParametersValidator = new DefaultJobParametersValidator(
    	new String[] { "fileName" },
        new String[] { "name", "run.id" });
    ...
}

@Bean 
public Job job() {
	return this.jobBuilderFactory.get("basicJob")
    	.start(step1())
        .validator(validator())
        .incrementer(new RunIdIncrementer())
        .build();
	}
}

//	DailyJobTimestamper
//	Custom Incrementer
//	currentDate를 유효성 검증기에 추가해야 함
public class DailyJobTimestamper implements JobParametersIncrementer {
	@Override
    public JobParameters getNext(JobParameters parameters) {
    	return new JobParametersBuilder(parameters)
        	.addDate("currentDate", new Date())
            .toJobParameters();
	}
}

@Bean
public CompoisteJobParameterValidator validator() {
	...
    DefaultJobParametersValidator defaultJobParametersValidator = new DefaultJobParametersValidator(
    	new String[] { "fileName" },
        new String[] { "name", "currentDate" });
    ...
}

@Bean 
public Job job() {
	return this.jobBuilderFactory.get("basicJob")
    	.start(step1())
        .validator(validator())
        .incrementer(new DailtJobTimestamper())
        .build();
	}
}

Step

0개의 댓글