웹 프레임워크에는 MVC 패턴이라는 것이 있고 특정 MVC 프레임워크를 이해하고 나면 다른 MVC 프레임워크를 사용하더라도 서로 다른 문법적 차이만 이해하면 된다. 그러나 배치 프레임워크는 종류가 많지 않다. 그래서 배치 프레임워크는 분야가 조금 생소할 수 있다. 
job(잡)이나 Step(스텝)이 무엇인지?
ItemReader와 ItemWriter가 어떻게 연관돼 있는지
Tasklet이 무엇인지?
2장에서는 위의 질문에 대한 답을 할 것이다.


잡과 스텝

배치 잡

ex) 은행업무
Step1 : 다른 시스템에서 수신한 거래 정보 파일을 읽어와 데이터베이스에 저장한다.
Step2 : 모든 입금 정보를 계좌에 반영한다.
Step3 : 모든 출금정보를 계좌에 반영한다.

 

각 스텝은 잡을 구성하는 독립된 작업의 단위라는 것을 알 수 있다.

스탭

  • 테스크릿(tasklet) 기반 스텝
  • 청크(chunk) 기반 스텝

테스크릿(tasklet) 기반 스텝

스텝이 중지될 때까지 execute 메서드가 반속해서(execute 메서드를 호출할 때마다 독립적인 트랜잭션이 얻어짐) 수행 된다. 

  • 초기화
  • 저장 프로시저 실행 
  • 알람 전송

청크(chunk) 기반 스텝

약간 스텝의 구조가 복잡하며, 아이템 기반의 처리가 사용된다. 

  • ItemReader(필수)
  • ItemProcessor(선택)
  • ItemWriter(필수)

ItemReader와 ItemWrier만으로 구성해 스텝을 진행 할 수도 있다.(이러한 스텝은 데이터 마이그레이션 잡에 일반적으로 사용된다.)

 

배치 잡을 구성하는 인터페이스

인터페이스 설명
org.springframework.batch.core.Job ApplicationContext 내에 구성되는 잡 객체
org.springframework.batch.core.Step ApplicationContext 내에 구성되는 스텝을 나타내는 객체
org.springframework.batch.core.step.tasklet.Tasklet 트랜잭션 내에서 로직이 실행 될 수 있는 기능을 제공하는 전략(Strategy) 인터페이스
org.springframework.batch.item.itemReader<T> 스텝 내에서 입력을 제공하는 전략 인터페이스
org.springframework.batch.item.itemProccesor<T> 스텝 내에서 제공받은 개별 아이템(item)에 업무 로직, 검증 등을 적용하는 역할을 하는 인터페이스
org.springframework.batch.item.itemWriter<T> 스텝 내에서 아이템을 저장하는 전략 인터페이스

 

잡 실행

JobRepository

JobLauncher

개발자가 구현하기에 따라 역할이 달라진다.

  • Job.execute메서드를 호출하는 역할 
  • 잡의 재실행 가능 여부 검증(모든 잡을 재시작할 수 있는 것은 아님)
  • 잡의 실행 방법(현재 스레드에서 수행할지 스레드 풀을 통해 실행할지 등)
  • 파라미터 유효성 검증

잡을 실행하면, 해당 잡은 각 스텝을 실행한다. 각 스텝이 실행되면 JobRepository는 현재 상태로 갱신된다. 즉, 실행된 스텝, 현재 상태, 읽은 아이템 및 처리된 아이템 수 등이 모두 JobRepository에 저장된다.

 

병렬화

가장 단순한 방법은 배치 처리 아키텍처는 잡 내의 스텝을 처읍부터 끝까지 순서대로 단일 스레드에서 진행하는 것이다. 하지만 스프링 배치는 실 사례에 필요한 벙렬화 방버을 제공한다. 

  • 다중 스레드 스텝을 통한 작업 분할
  • 전체 스텝의 병렬 실행
  • 비동기 ItemProcessor/ItemWriter 구성
  • 원격 청킹
  • 파티셔닝

package io.spring.batch.helloworld;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

//새롭게 추가1
@EnableBatchProcessing
@SpringBootApplication
public class HelloWorldApplication {
//새롭게 추가2
	@Autowired
	private JobBuilderFactory jobBuilderFactory;
//새롭게 추가3
	@Autowired
	private StepBuilderFactory stepBuilderFactory;

	@Bean
	public Step step() {
		return this.stepBuilderFactory.get("step1")
				.tasklet(new Tasklet() {
					@Override
					public RepeatStatus execute(StepContribution contribution,
							ChunkContext chunkContext) {
						System.out.println("Hello, World!");
						return RepeatStatus.FINISHED;
					}
				}).build();
	}

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

	public static void main(String[] args) {
		SpringApplication.run(HelloWorldApplication.class, args);
	}
}

 

@EnableBatchProcessing 에너테이션의 역할

이 에너테이션은 배치 인프라스트럭처를 위한 대부분의 스프링 빈 정의를 제공하므로 다음과 같은 컴포넌트를 직접 포함시킬 필요는 없다

컴포넌트 설명
JobRepository 실행 중인 잡의 상태를 기록하는 데 사용됨
JobLauncher 잡을 구동하는 데 사용됨
JobExplorer JobRepository를 사용해 읽기 전용 작업을 수행하는 데 사용
JobRegistry 특정한 런처 구현체를 사용할 때 잡을 찾는 용도로 사용됨
PlatformTransactionManager 잡 진행 과정에서 트랜잭션을 다루는 데 사용됨
JobBuilderFactory 잡을 생성하는 빌더
StepBuilderFactory 스텝을 생성하는 빌더

 

@SpringBootApplication 에너테이션의 역할

@componenetScan과 @EnableAutoConfiguration을 결합한 메타 에너테이션이다. 이 에너텡션은 데이터 소스뿐만 아니라 스프링 부트 기반의 적절한 자동 구성을 만들어 준다. 

 

public Step step()

이 잡은 단일 스텝으로 구성되므로 간단하게 스텝이름만 지정한다. 스텝은 스프링 빈으로 구성됐으며, 이 간단한 예제에서는 두가지 요인인 이름 및 테스크릿만 필요하다.  System.out.println("Hello, World")을 호출한 다음에 RepeatStatus.FINISHED를 반환한다.

RepeatStatus  
RepeatStatus.FINISHED 테스크릿(Tasklet)이 완료됐음을 뜻함.
RepeatStatus.CONTINUEBLE 테스크릿(Tasklet)을 다시 호출

JobBuilderFactory

잡 이름과 해당 잡에서 시작할 스텝을 구성한다.

 


잡 실행하기

잡은 첫 번째 스텝을 실행했다. 이때 트랜잭션이 시작하며, Tasklet이 실행됐고, 결과가 JobRepository에 갱신됐다. 

 

+ Recent posts