반응형
FlowJob
- Step을 순차적으로만 구성하는 것이 아닌 특정한 상태에 따라 흐름을 전환하도록 구성할 수 있으며 FlowJobBuilder에 의해 생성된다.
- Flow와 Job의 흐름을 구성하는데만 관여하고 실제 비즈니스 로직은 Step에서 이루어진다.
- 내부적으로 SimpleFlow 객체를 포함하고 있으며 Job 실행 시 호출한다.
사용해야하는 경우
- Step이 실패하더라도 Job은 실패로 끝나지 않도록 해야 하는 경우
- Step이 성공했을 때 다음에 실행해야 할 Step을 구분해서 실행해야 하는 경우
- 특정 Step은 전혀 실행되지 않게 구성해야 하는 경우
- 조건적 흐름이 필요하면 FloJob, 순차적 흐름은 SimpleJob 활용
배치 상태 유형
BatchStatus
- JobExecution과 StepExecution의 속성으로 Job과 Step의 종료 후 최종 결과 상태가 무엇인지 정의
- COMPLETED, STARTING, STARTED, STOPPING, STOPPED, FAILED, ABANDONED, UNKNOWN가 있다.
- ABANDONED 는 처리를 완료했지만 성공하지 못한 단계와 재시작시 건너 뛰어야하는 단계
SimpleJob
- 마지막 Step의 BatchStatus 값을 Job의 최종 BatchStatus 값으로 반영
- Step이 실패할 경우 해당 Step이 마지막 Step이 된다.
FlowJob
- Flow 내 Step의 ExitStatus 값을 FlowExecutionStatus 값으로 저장
- 마지막 Flow의 FlowExecutionStatus 값을 Job의 최종 BatchStatus 값으로 반영
ExitStatus
- JobExecution과 StepExecution의 속성으로 Job과 Step의 실행 후 어떤 상태로 종료되었는지 정의
- 기본적으로 ExitStatus는 BatchStatus와 동일한 값으로 설정된다.
- UNKNOWN, EXECUTING, COMPLETED, NOOP, FAILED, STOPPED
SimpleJob
- 마지막 Step의 ExitStatus 값을 Job의 최종 ExitStatus 값으로 반영
FlowJob
- Flow 내 Step의 ExitStatus 값을 FlowExecutionStatus 값으로 저장
- 마지막 Flow의 FlowExecutionStatus 값을 Job의 최종 ExitStatus 값으로 반영
FlowExecutionStatus
- FlowExecution의 속성으로 Flow의 실행 후 최종 결과 상태가 무엇인지 정의
- Flow내 Step이 실행되고 나서 ExitStatus 값을 FlowExecutionStatus 값으로 저장
- FlowJob의 배치 결과 상태에 관여함
- COMPLETED, STOPPED, FAILED, UNKNOWN
Transition
- Flow 내 Step의 조건부 전환(전이)을 정의함
- Job의 API 설정에서 on(String pattern) 메서드를 호출하면 TransitionBuilder가 반환되어 Transition Flow를 구성할 수 있음
- Step의 종료 상태(ExitStatus)가 어떤 pattern과도 매칭되지 않으면 스프링 배치에서 예외를 발생하고 Job은 실패
- transition은 구체적인 것부터 그렇지 않은 순으로 적용된다
api
- on(String pattern)
- Step의 실행 결과로 돌려받는 ExitStatus와 매칭하는 패턴 스키마, BatchStatus와 매칭하는 것이 아니다.
- pattern과 ExitStatus와 매칭이되면 다음으로 실행할 Step을 지정할 수 있다.
- to()
- 다음으로 실행할 단계를 지정
- from()
- 이전 단계에서 정의한 Transition을 새롭게 추가 정의함
Job을 중단하거나 종료하는 Transition API
Flow가 실행되면 FlowExecutionStatus에 상태값이 저장되고 최종적으로 Job의 BatchStatus와 ExitStatus에 반영된다.
Step의 BatchStatus 및 ExitStatus에는 아무런 영향을 주지 않고 Job의 상태만을 변경한다.
- stop()
- FlowExecutionStatus가 STOPPED 상태로 종료되는 transition
- Job의 BatchStatus와 ExitStatus가 STOPPED으로 종료됨
- fail()
- FlowExecutionStatus가 FAILED 상태로 종료되는 transition
- Job의 BatchStatus와 ExitStatus가 FAILED으로 종료됨
- end()
- FlowExecutionStatus가 COMPLETED 상태로 종료되는 transition
- Job의 BatchStats와 ExitStatus가 COMPLETED으로 종료됨
- Step의 ExitStatus가 FAILED이더라도 Job의 BatchStatus가 COMPLETED로 종료하도록 가능하며 이 때 Job의 재시작은 불가능함
- stopAndRestart()
- stop() transition과 기본 흐름은 동일
- 특정 step에서 작업을 중단하도록 설정하면 중단 이전의 Step만 COMPLETED 저장되고 이후의 step은 실행되지 않고 STOPPED 상태로 Job 종료
- Job이 다시 실행됐을 때 실행해야 할 step을 restart 인자로 넘기면 이전에 COMPLETED로 저장된 step은 건너뛰고 중단 이후 step 부터 시작한다.
JobExecutionDecider
- ExitStatus를 조작하거나 StepExecutionListener를 등록할 필요 없이 Transition 처리를 위한 전용 클래스
- Step과 Transition 역할을 명확히 분리해서 설정할 수 있음
- Step의 ExitStatus가 아닌 JobExecutionDecider의 FlowExecutionStatus 상태값을 새롭게 설정해서 반환함
FlowJob 아키텍쳐
SimpleFlow
- 스프링 배치에서 제공하는 Flow 구현체로서 각 요소(Step, Flow, JobExecutionDecider)을 담고 있는 State를 실행시키는 도메인 객체
- FlowBuilder를 사용해서 생성하여 Transition과 조합하여 여러 개의 Flow 및 중첩 Flow를 만들어 Job을 구성할 수 있다.
- SimpleFlow를 구성하고 있는 모든 Step들이 Transition에 따라 분기되어 실행된다.
- StimpleFlow 내 SimpleFlow를 2중, 3중으로 중첩해서 복잡하게 구성할 수 있다.
아키텍쳐
- State Transition은 현재 실행할 State와 다음 실행할 State의 정보를 가진다.
- State 인터페이스의 구현 클래스는 Step, Flow, JobExecutionDecider의 각 요소를 저장한다.
- Flow를 구성하면 내부적으로 생성되어 Transition과 연동
- handle() 메서드 실행 후 FlowExecutionStatus 변환
- on(pattern)의 pattern 값과 매칭여부 판단
- 마지막 실행 상태가 FlowJob의 최종 상태가 됨
- SimpleFlow는 StateMap에 저장되어 있는 모든 State들의 handle 메서드를 호출해서 모든 Step들이 실행되도록 한다.
- SimpleFlow는 현재 호출되는 State가 어떤 타입인지 알지 못하고 관심도 없다. 단지 handle 메서드를 실행하고 상태값을 얻어올 뿐이다. (상태 패턴)
FlowStep
- Step 내에 Flow를 할당하여 실행시키는 도메인 객체
- flowStep의 BatchStatus와 ExitStatus은 Flow의 최종 상태값에 따라 결정된다.
@JobScope / @StepScope
Scope란 스프링 빈이 관리되는 범위이다.
singleton, prototype, request, session, application 있으며 기본은 singleton 으로 생성됨
스프링 배치 스코프
- @JobScope와 @StepScope가 있다.
- Job 과 Step 의 빈 생성과 실행에 관여하는 스코프
- 프록시 모드를 기본값으로 하는 스코프
- @Scope(value = "job", proxyMode = ScopedProxyMode.TARGET_CLASS)**
- 해당 스코프가 선언되면 빈이 생성이 어플리케이션 구동시점이 아닌 빈의 실행시점에 이루어진다
- @Values를 주입해서 빈의 실행 시점에 값을 참조할 수 있으며 일종의 Lazy Binding 이 가능해 진다
- @Value("#{jobParameters[파라미터명]}"), @Value("#{jobExecutionContext[파라미터명]”}), @Value("#{stepExecutionContext[파라미터명]”})
- @Values 를 사용할 경우 빈 선언문에 @JobScope , @StepScope 를 정의하지 않으면 오류를 발생하므로 반드시 선언해야 함
- 프록시 모드로 빈이 선언되기 때문에 어플리케이션 구동시점에는 빈의 프록시 객체가 생성되어 실행 시점에 실제 빈을 호출해 준다.
- 병렬처리 시 각 스레드 마다 생성된 스코프 빈이 할당되기 때문에 스레드에 안전하게 실행이 가능하다.
@JobScope
- Step 선언문에 정의한다.
- @Value: jobParameter, JobExecutionContext만 사용 가능
@StepScope
- Tasklet이나 ItemReader, ItemrWriter, ItemProcessor 선언문에 정의한다.
- @Value: jobParameter, jobExecutionContext, stepExecutionContext 사용 가능
아키텍쳐
Proxy 객체 생성
- @JobScope, @StepScope 애노테이션이 붙은 빈 선언은 내부적으로 빈의 Proxy 객체가 생성된다.
- @JobScope
- @Scope(value = "job", proxyMode = ScopedProxyMode.TARGET_CLASS)
- @StepScope
- @Scope(value = “step", proxyMode = ScopedProxyMode.TARGET_CLASS)**
- Job 실행 시 Proxy 객체가 실제 빈을 호출해서 메서드를 실행시키는 구조
JobScope, StepScope
- Proxy 객체의 실제 대상이 되는 Bean을 등록, 해제하는 역할
- 실제 빈을 저장하고 있는 JobContext, StepContext를 가지고 있다.
JobContext, StepContext
- 스프링 컨테이너에서 생성된 빈을 저장하는 컨텍스트 역할
- Job의 실행 시점에서 프록시 객체가 실제 빈을 참조할 때 사용됨
이상으로 포스팅을 마칩니다. 감사합니다.
참고자료
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B0%B0%EC%B9%98/dashboard
반응형
댓글