Batch 프로그램
정해진 시간에 일괄적으로 작업을 처리한다.
Batch 프로그램이 필요한 상황
1.
필요한 데이터를 모아서 처리해야 할 때
a.
월별 거래 명세서 생성
2.
일부러 지연시켜 처리 할 때
a.
주문한 상품을 바로 배송 처리 하지 않고, 일정 시간 뒤 처리
3.
자원을 효율적으로 활용하기 위해
a.
트래픽이 적은 시간 대에 서버 리소스를 활용
Spring Batch를 사용하는 이유
가볍고 다양한 기능을 가진 배치 프레임 워크이다. 견고한 배치 어플리케이션 개발이 가능하도록 디자인 되어있다.
그래서 스프링 배치를 사용하면 기능(로깅/추적, 트랜잭션 관리 등)을 잘 조합해서 우리가 원해는 배치 프로그램을 쉽게 구현 가능해진다.
Spring Batch 아키텍처
•
JobLauncher는 Job을 실행시키는 컴포넌트이다.
•
Job은 배치 작업, JobRepository는 Job 실행과 Job, Step을 저장
•
Step은 배치 작업의 단계. ItemReader 1개, ItemProcessor 1개, ItemWriter 1개씩 데이터를 읽고 처리하고 쓰는 구성
Spring Batch 아키텍처는 자세하게 Application Layer(개발자가 직접 Spring Batch를 사용하는 Layer)와 배치 작업을 시작하고 제어하는데 필수적인 클래스인 Core Layer(Job, Step, JobLaucher), 외부와 상호작용하는 Infrastructure Layer(ItemReader, ItemProcessor, ItemWriter)가 있다.
Job
•
전체 배치 프로세스를 캡슐화한 도메인
•
Step의 순서를 정의
•
JobParameters를 받음
Step
•
작업 처리의 단위
•
Chunk 기반 스텝, Tasklet 스텝 2가지로 나뉜다.
•
Chunk 기반 스텝은 하나의 트랜잭션에서 데이터를 처리한다.
•
commitInterval만큼 데이터를 읽고 트랜잭션 경계 내에서 chunkSize만큼 write를 한다.
chunkSize: 한 트랜잭션에서 쓸 아이템 갯수
commitInterval: reader가 한번에 읽을 아이템 개수
chunkSize>=commitInterval
Plain Text
복사
•
Tasklet 스텝은 하나의 트랜잭션에서 모든걸 처리하는 것을 말하며 단순한 경우 사용한다.
JobParameterValidator
JobParameter가 잘 못 들어오면 로직에서 에러 발생하게 하지 않고 애초에 실행되지 않게 하기 위해 사용.
1.
JobParameterValidator를 상속받아 validate를 오버라이딩
2.
Job 생성 시 .validator 추가
JobExecutionListener
Job이 실행되기 전 혹은 실행되고 나서의 상태를 확인하기 위해 사용
1.
JobExecutionListenre Bean 등록
2.
Job 생성 시 .listener 등록
FlatFileItemReader
파일을 읽도록 해주는 item reader
Chunk 기반으로 item들을 읽어들일 수 있다.
@Bean
@StepScope
public FlatFileItemReader<UserDto> userItemReader() {
return new FlatFileItemReaderBuilder<UserDto>()
.name("userItemReader")
.resource(new FileSystemResource(filePath + fileName))
.delimited().delimiter("|")
.names(new String[] {"userId", "passwd", "name","intValue"})
.targetType(UserDto.class)
.recordSeparatorPolicy(new SimpleRecordSeparatorPolicy() {
@Override
public String postProcess(String record) {
return record.trim();
}
})
.build();
}
Java
복사
1.
resource: 지정한 파일에서 데이터를 읽어올 수 있도록 resource 설정
2.
delimited/delimiter : 어떤 구분자로 구분할 것인지 지정, delimited()만 되어있으면 콤마로 지정
3.
names: 파일 내 각각의 컬럼명 지정
4.
targetType: 매핑되서 반환될 dto 지정
StepListener
@StepScope
@Bean
public StepExecutionListener stepExecutionListener() {
return new StepExecutionListener() {
@Override
public void beforeStep(StepExecution stepExecution) {
log.info("[StepExecutionListener] before : {}", stepExecution.getStatus());
}
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
log.info("[StepExecutionListener] after : {}", stepExecution.getStatus());
return stepExecution.getExitStatus();
}
};
}
Java
복사