Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- JDK1.3
- gradle
- 애드센스 수익
- Spring Batch
- 도커
- docker mysql
- python
- 젠킨스
- docker 명령어
- apache log4j
- Vue 배우기
- Vue 강의
- spring boot 시작
- scrapy
- python 기초
- 티스토리 광고 수익
- intelliJ plugin
- Vue
- 미국주식
- Spring
- 구글 애드센스 수익
- Vue 알아보기
- docker
- 미국 배당주
- Python 기본편
- Spring Batch 강의
- MYSQL
- IntelliJ
- spring Annotation
- AES256
Archives
나만의공간
Spring Batch #8 (Job의 이해) 본문
JobLauncherApplicationRunner
- Spring Batch 작업을 시작하는 ApplicationRunner로서 BatchAutoConfiguration에서 생성
- 스프링 부트에서 제공하는 ApplicationRunner의 구현체로 어플리케이션이 정상적으로 구동되자 마자 실행됨
- 기본적으로 Bean으로 등록된 모든 Job을 실행 시킵니다.
BatchProperties
- application.yml 에서 Spring Batch 의 환경 설정을 할 수 있음
spring:
batch:
job:
enabled: true
names: ${job.name:NONE}
jdbc:
initialize-schema: always
table-prefix: SYSTEM_
- enabled
- 기본값은 true
- false는 스프랑이 자동으로 job을 실행하는 것을 막습니다.
- names
- enabled이 true일 때, 자동으로 전체 Job이 실행되는데 특정 Job만 실행하도록 하는 옵션입니다.
- 여러개 작성시 쉼표(,)로 구분합니다.
- 하드코딩으로 넣어도 되지만 위처럼 사용하면 실행 시 argument로 주입받아서 사용할 수 있습니다.
- --job.name=job1,job2
- job1,job2만 실행하고 존재하지 않으면 실행하지 않습니다.
- 만약 아무런 argument가 주입되지 않는다면 아무런 배치도 실행되지 않습니다.
- initialize-schema
- EMBEDED: 내장 DB일 때만 실행되며 스키마가 자동으로 생성(Default)
- ALWAYS: 스키마 자동생성 Script 항상 실행
- NEVER
- 스크립트 항상 실행 안하기 때문에 내장DB일 경우 스키마 미생성으로 오류 발생
- 운영에서는 수동으로 스크립트 생성하는 것을 권장함.
- table-prefix
- Spring Batch Meta Table 생성시 테이블 앞의 문자 변경 옵션
- 기본값은 BATCH_ 임
JobBuilderFactory, JobBuildr 란
스프링 배치는 Job을 쉽게 생성 및 설정할 수 있도록 Util 성격의 빌더 클래스들을 제공합니다.
- JobBuilderFactory
- JobBuilder를 생성하는 팩토리 클래스로 get 메서드를 제공합니다.
- JobBuilderFactory.get("jobName")
- 내부적으로 JobBuildr가 JobName을 잡의 이름으로 하여 잡을 생성하도록 로직이 구성되어 있습니다.
- JobBuilder
- Job을 구성하는 설정 조건에 따라 두 개의 하위 빌더 클래스를 생성하여 직접 Job을 생성하지 않고 Job 생성을 위임합니다.
- SimpleJobBuilder
- SimpleJob을 생성하는 Builder 클래스
- Job 실행과 관련된 여러 설정 API 제공
- FlowJobBuilder
- FlowJob을 생성하는 Builder 클래스
- 내부적으로 FlowBuilder를 반환함으로써 Flow 실행과 관련된 여러 설정 API를 제공
- JobBuilderFactory에서 get메소드를 통해 JobBuilder 클래스를 생성
- JobBuilder에서 start(step)를 사용하면 JobBuilder 내부적으로 SimpleJobBuilder를 생성하여 SimpleJob을 생성합니다.
- JobBuilder에서 start(flow) 또는 flow(step)을 사용하면 JobBuilder 내부적으로 FlowJobBuilder를 생성하여 FlowJob을 생성합니다.
FlowJobBuilder는 내부적으로 JobFlowBuilder 클래스를 생성하여 Flow를 생성합니다. - SimpleJobBuilder와 JobFlowBuilder는 위 그림과 같이 다양한 API를 제공합니다.
상속구조
- JobBuilderFactory는 JobBuilder 클래스를 생성하는 역활을 함
- JobBuilder 클래스는 JobBuilderHelper를 상속받음.
- JobBuilderHelper 클래스는 내부 static 클래스로 CommonJobProperties를 갖고 있으며, 이를 필드값으로 Job을 생성하는 공통적인 내용을 갖고 있다고 보면 됩니다.
- JobFactory에서 JobBuilder를 생성할 때 생성자의 인자로 JobRepository를 넘기는데 이게 JobBuilder에 CommonJobProperties에 담기게 됩니다.
- JobBuilder가 생성하는 SimpleJobBuilder와 FlowJobBuilder는 JobBuilderHelper를 상속받고 있음
- SimpleJobBuilder와 FlowJobBuilder는 각각 Job을 생성하게 되고, JobRepository는 빌더 클래스를 통해 Job 객체에 전달되어 메타데이터를 기록하는데 사용됩니다.
SimpleJob
- SimpleJob은 Step을 실행시키는 Job 구현체로서 SimpleJobBuilder에 의해 생성된다.
- 여러 단계의 Step으로 구성할 수 있으며, Step을 순차적으로 실행 시킵니다.
- 모든 Step의 실행이 성공적으로 완료되어야 Job이 성공적으로 완료 됩니다.
- 맨 마지막에 실행한 Step의 BatchStatus가 Job의 최종 BatchStatus가 됩니다.
기본API
validator()
- Job 실행에 꼭 필요한 파라미터를 검증하는 용도
- DefaultJobParameterValidator 구현체를 지원함.
동작과정
예제
Validator를 실행하는 배치Job
package com.study.springbatch.domain.job;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameter;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.JobParametersValidator;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.job.DefaultJobParametersValidator;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
* 사용자 Parameter Validtion 학습
*/
@Slf4j
@Configuration
@RequiredArgsConstructor
public class Study8JobConfig {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
@Bean
public Job study8() {
return jobBuilderFactory.get("study8")
.start(study8Step1())
//사용자 정의 Validator 사용법
.validator(new CustomerParameterValidator())
// 기본 Validation 사용방법
// .validator(new DefaultJobParametersValidator(new String[] {"name","date"}, new String[]{"count"} ))
.build();
}
@Bean
public Step study8Step1() {
return stepBuilderFactory.get("study8Step1")
.tasklet((stepContribution, chunkContext) -> {
System.out.println("study8Step1 executed");
return RepeatStatus.FINISHED;
})
.build();
}
}
사용자정의 Validator 클래스
package com.study.springbatch.domain.job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.JobParametersValidator;
public class CustomerParameterValidator implements JobParametersValidator {
@Override
public void validate(JobParameters parameters) throws JobParametersInvalidException {
// name값이 "aaaa"가 아니면 오류 발생
if (!parameters.getString("name").equals("aaaa")) {
throw new JobParametersInvalidException("name 값이 올바른 값이 아닙니다.");
}
}
}
preventRestart()
package com.study.springbatch.domain.job;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
* Job 메소드 중 preventRestart 테스트
* preventRestart를 호출하면 false인 상태로 동작 합니다.
* preventRestart를 미호출 하면 true인 상태로 동작 합니다.
*
* preventRestart
* -. 기본적으로 Job이 실패할경우 재시작이 가능한데 해당값을 false로 주게 되면
* -. 재시작을 지원하지 않습니다.
*/
@RequiredArgsConstructor
@Slf4j
@Configuration
public class PreventRestartJobConfig {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
@Bean
public Job preventRestartJob() {
return jobBuilderFactory.get("preventRestartJob")
.start(preventRestartStep())
/**
* preventRestart 호출 하면 false로 세팅
* preventRestart 미호출 하면 true로 세팅
*/
// .preventRestart()
.build();
}
@Bean
public Step preventRestartStep() {
return stepBuilderFactory.get("preventRestartStep")
.tasklet((stepContribution, chunkContext) -> {
log.info("preventRestartStep 테스트");
return RepeatStatus.FINISHED;
})
.build();
}
}
incrementer()
- JobParameters로 Job이 성공했다면 기본적으로 동일한 JobParameters로 동일한 Job을 실행시킬 수 없음.
- 하지만 같은 JobParameters로 계속 Job을 실행해야 할 때가 있음.
- 이떄 JobIncrementer를 사용합니다.
- 즉, 기존의 JobParameter 변경없이 Job을 여러 번 시작하고자 할 때 사용 합니다.
- Incrementer는 특별한 일을 하는것이 아니라 실행되기 위해 주입된 파라미터에 추가로 파라미터를 더해주는 역활만 함.
- 구현체로 지원하는 RunIdIncrementer()의 경우 run.id라는 키로 실행될 때마다 1부터 증가함.
package com.study.springbatch.domain.job;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.JobParametersIncrementer;
public class CustomerJobParametersIncrementor implements JobParametersIncrementer {
public static final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-hh");
@Override
public JobParameters getNext(JobParameters parameters) {
String id = sdf.format(new Date());
return new JobParametersBuilder().addString("customer",id).toJobParameters();
}
}
package com.study.springbatch.domain.job;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
* incrementer 기능 테스트
*
*/
@RequiredArgsConstructor
@Slf4j
@Configuration
public class IncrementJobConfig {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
@Bean
public Job incrementJob() {
return jobBuilderFactory.get("incrementJob")
.start(incrementStep())
//사용자 정의 패턴
// .incrementer(new CustomerJobParametersIncrementor())
//기본 패턴
.incrementer(new RunIdIncrementer())
.build();
}
@Bean
public Step incrementStep() {
return stepBuilderFactory.get("incrementStep")
.tasklet((stepContribution, chunkContext) -> {
log.info("확인 Job 기능: increment");
return RepeatStatus.FINISHED;
})
.build();
}
}
SimpleJob 흐름도
- JobLauncher는 SimpleJob과 JobParameters를 갖고 Job을 실행 시킴
- Job이 실행될 때 필요한 메타 데이터들을 생성함
- Job이 실행되기 전에 JobListener에서 beforeJob이 호출
- 각 Step이 실행되면서 StepExecution과 ExecutionContext가 생성됨.
- Step이 종료되면 JobListener에서 afterJob이 호출
- 마지막 Step 단계의 BatchStatus와 ExitStatus를 Job에 업데이트시키고 끝
'IT > Spring Batch' 카테고리의 다른 글
Spring Batch #10 (Flow / Scope 의 이해) (0) | 2023.10.26 |
---|---|
Spring Batch #9 (Step의 이해) (0) | 2023.10.16 |
Spring Batch #7(도메인 이해) (0) | 2023.10.10 |
Spring Batch 강의 #6(배치란?) (0) | 2023.09.25 |
Spring Batch 강의 #5(Spring Batch 메타 테이블 구조) (0) | 2023.09.22 |
Comments