Search
Duplicate

5. 스프링 배치 도메인 이해하기

목차

1. 개요

지난 글에서 DB Schema까지 분석을 해봤는데, Job, Step등에 대해서 간략하게는 소개했지만, 아직 정확히 이게 어떠한 동작을하는지 어떤 도메인인지 알아보지 못했다. 이번 챕터에서는 Job, Step그리고 ExecutionContext나 JobRespository, JobLauncher등의 스프링 배치에서 핵심이 되는 도메인들에 대해서 알아보는 시간을 가질 것이다.

2. Job

배치 계층 구조의 최상위 개념으로 하나의 배치작업 자체를 의미하는 Job 객체는 예를들어 API서버의 접속 로그 데이터를 통계 서버로 옮기는 배치작업 자체가 Job이라 할 수 있다. 이러한 Job객체는 일종의 명세서 역할도 하고 있는데, 외부적으로는 Job Configuration을 통해 생성되고, 내부적으로는 배치 작업을 어떻게 구성 및 실행할지에 대한 명세가 설정되어 있다. 스프링 배치에선 이런 Job에 대한 기본 구현체를 제공하기에 우리는 이 기본 구현체를 이용하여 Job을 제공할 수 있다.
Job 구현체를 생성할 때 해당 객체는 여러 Step을 포함할 수 있는 컨테이너 역할을 하는데, 당연하게도 반드시 하나 이상의 Step은 있어야 한다.

스프링 배치가 제공하는 기본 구현체

SimpleJob
순차적으로 Step을 실행시키는 Job 구현체
모든 Job에서 유용하게 사용할 수 있는 표준 기능을 가지고 있다.
FlowJob
특정한 조건과 흐름에 따라 Step을 구성하여 실행시키는 Job으로 Flow객체를 실행시켜 작업을 진행한다.
Ex: Step1실행 후 조건에 따라 Step2가 아닌 StepN을 실행할 수 있다.

Job Layered Architecture

JobLauncher는 Job에 필요한 파라미터 정보(JobParameter)와 job 객체를 run() 메서드에 인자로 전달해서 실행시키고 Job 내부적으로는 execute() 메서드로 각각의 Step들을 구동한다. 이 때 Step을 어떻게 구동할지(순차적으로 할지, 조건에 따라 나뉠지)에 대해서는 각각의 구현체별로 다른 방식을 가질 수 있다.

Job Interface & AbstractJob

Job Interface는 execute 메서드는 JobExecution이라는 도메인 객체를 인수로 전달받아 실행하는 메서드가 정의되어 있다.
AbstractJob은 여러 필드를 가지고 있는데, 각각의 정보는 다음과 같다.
name: Job 이름
restartable: 재시작 여부(default true)
JobRepository: 메타데이터 저장소
JobExecutionListener: Job 이벤트 리스터로 Job이 실행될 때 리스너를 등록하면 이벤트 발생 시점에 리스너가 동작을 수행한다.
JobParametersIncrementer: JobParameter 증가기
JobParametersValidator: JobParameter 검증기
SimpleStepHandler: Step 실행 핸들러

Job이 실행되기까지의 흐름

간단하게 작성해본 job이 어떻게 실행되는지 스텝바이스텝으로 살펴보자.
@Configuration @RequiredArgsConstructor public class JobConfiguration { private final JobBuilderFactory jobBuilderFactory; private final StepBuilderFactory stepBuilderFactory; @Bean public Job job() { return jobBuilderFactory.get("job") .start(step1()) .next(step2()) .build(); } @Bean public Step step1() { return stepBuilderFactory.get("step1") .tasklet(((contribution, context) -> { System.out.println("step1 was executed"); return RepeatStatus.FINISHED; })).build(); } @Bean public Step step2() { return stepBuilderFactory.get("step2") .tasklet(((contribution, context) -> { System.out.println("step2 was executed"); return RepeatStatus.FINISHED; })).build(); } }
Java
복사
간단한 Job 등록 설정 파일

1. jobBuilderFactory.get("job")

get(”job”) 메서드는 JobBuilderHelper 추상클래스에서 관리하는 프로퍼티중 name의 이름으로 지정되어 JobBuilder 객체(여기서는 SimpleJobBuilder를 기준으로 하자.) 가 생성되고 해당 빌더를 반환한다. (JobBuilder는 JobBuilderHelper를 상속하는 자식 클래스다.)

2. start(step1())

step1() 메서드의 결과로 반환되는 Step 정보를 start메서드는 첫 번째 인덱스에 저장하고 자기자신(Builder)을 반환하여 메서드 체이닝을 지원한다.

3. next(step2())

steps 컬렉션에 두 번때 step정보를 추가하고 자기자신(builder)을 반환한다.

4. build()

SimpleJob 객체를 만들고, 전달한 데이터들(name, steps, ..)을 담는다. setSteps는 addAll메서드로 steps가 가진 모든 step정보를 모두 담는다.

ETC. 만들어진 Job을 실행시키는 JobLauncherApplicationRunner

위의 과정들을 거쳐 스프링 빈으로 등록된 여러 Job들을 실행시켜주는 JobLauncher는 BatchAutoConfiguration 설정 클래스에서 스프링 빈으로 등록된다.
BatchAutoConfiguration의 jobLauncerApplicationRunner 스프링 빈
이렇게 생성된 JobLauncherApplicationRunner는 execute라는 메서드를 통해 Job을 실행시킨다.
JobLauncherApplicationRunner의 execute 메서드
소스를 보면 자체적으로 가지고 있는 JobLauncher를 이용해 run을 호출하고 인수로 실행시킬 job과 해당 잡에 필요한 파라미터 정보인 jobParameters를 전달한다. 여기서 run메서드를 살펴보고싶다면 SimpleJobLauncher의 run 메서드를 살펴보면 된다.

3. Step

4. ExecutionContext

5. JobRepository / JobLauncher

다음 글

이전 글