본문 바로가기

프로그래밍/우아한Tech

[우아한테크세미나] 190926 우아한스프링배치 by 우아한형제들 이동욱님

728x90
반응형

위 동영상을 보고 정리한 자료입니다.

 

Web vs Batch

Web - 실시간 처리/ 상대적인 속도/ QA 용이성

Batch - 후속 처리 / 절대적인 속도 / QA 복잡성

 

* Batch는 테스트 코드가 필수

 

Spring Batch 와 Quartz

Quartz는 스케쥴링 프레임워크

ex: 매 시간 / 마지막 주 금요일에 실행

 

Quartz는 Spring Batch의 보안제 역할이지 대체제가 아니다.

 

배치 애플리케이션이 필요한 상황

일정 주기로 실행되어야 할 때

실시간 처리가 어려운 대량의 데이터를 처리 할 때

 

한달에 한번 실행된다는 의미는

한달 동안 쌓인 모든 데이터가 대상이라는 의미

즉, 대용량 데이터 처리가 절대적인 요구 사항

 

스프링 배치에서는 

모든 데이터를 메모리에 쌓지 않는

조회 방식이 기본 방식

 

jpaRepository.findAlll() 

방식으로 진행해선 안됩니다.

 

Job / Step / Tasklet 등등

* chunk : commit 단위

 

@JobScope, @StepScope, JobParameter

 

Spring Batch는 외부에서 파라미터를 주입받아

Batch 컴포넌트에서 사용 할 수 있다.

이를 JobParameter 라고 한다.

 

사용법: @Value("#{jobParameters[파라미터명]}") 타입 이름

 

Step에서 사용할 수 있는 @JobScope

Tasklet / Reader / Processor / Writer

에서 사용할 수 있는 @StepScope

Spring Batch의 JobParameter는

Long / String / Double / Date 타입들을 모두 지원합니다.

Enum / LocalDate / LocalDateTime은 지원 안됩니다.

@Value의 특성을 이용하자

 

JobParameter

 

@JobScope 와 @SetpSope 는 Late Binding(늦은 할당)

@JobScope - Job 실행 시점에 Bean 생성

@StepScope - Step 실행 시점에 Bean 생성

애플리케이션 실행 시점이 아님

 

애플리케이션 실행 후에도 동적으로

reader / processor / writer

bean 생성이 가능하다

 

JobParameter 값에 따라 Reader와 Processor를 교체

* 파라미터랑 읽어야 할 테이블만 다른 경우

 

활용편

 

관리 도구들

Cron

Spring MVC + API Call

Spring Batch Admin (Deprecated) 

Quartz + Admin

CI Tools (Jenkins / Teamcity 등등)

 

Jenkins를 비롯한 CI 도구

 

Jenkins의 장점

Integration (Slack, Email 등)

실행 이력 / 로그 관리 / Dashboard

다양한 실행 방법 (Rest API / 스케줄링 / 수동 실행)

계정 별 권한 관리

파이프라인

Web UI + Script 둘다 사용 가능

Plugin (Ansible, Github, Logentries 등)

 

Jenkins에서 Spring Batch 실행

 

일반적인 배치 Jar 실행 명령어 (--job.name은 스프링 환경 변수)

java -jar Application.jar \

-- job.name=job 이름 \

job파라미터이름1=job파라미터값1 \

job파라미터이름2=job파라미터값2 \

Jenkins 공통 설정 관리

이 외에도 xmx / xms 등등 추가 JVM 설정들이 많음

무중단 배포

CodeDeploy 대신 SCP로 동일하게 수행 가능

 

기존에 실행되고 있는 Batch jar를 종료하지 않고 배포 할 수 있을까?

마법의 명령어

readlink

모든 Job 마다 $(readlink /../app.jar) 를 선언해야 하나??

goto Jenkins공통 설정 관리

readlink를 공통설정으로

같은 Job인데 스케쥴만 다르게 / 파라미터만 다르게 하고 싶으면 어떡하지?

원본 Job 변경을 한 곳에서 하기 위해 파이프라인 사용합니다.

여러 Job을 순서대로 실행도 하고 싶고

개별로도 실행하고 싶을땐 어떡하지?

여러 작업이 순차적으로 실행이 필요할때

Step으로 나누기 보다는

파이프라인을 우선 고려한다.

 

멱등성

연산을 여러번 적용하더라도 결과가 달라지지 않는 성질

 

애플리케이션 개발에서 멱등성이 깨지는 경우

> 제어할 수 없는 코드를 직접 생성할 때

코드를 임시 수정 & 임시 배포해서 배치를 돌리고 다시 롤백한다.

그럼 젠킨스에서 오늘 일자를 yyyy-MM-dd로 보낼수 이지?

젠킨스 파라미터를 LocalDate처럼 사용할 순 없을까?

테스트 코드

JobName이 환겨변수로 넘어올때만

배치 Config를 활성화 한다.

테스트 케이스 100개가 넘기 시작하면서

기하 급수적으로

느려지는 전체 테스트 수행 속도

 

범인은 바로!

@ConditionalOnProperty

스프링은 전체 테스트 수행시

Environment가 변경될 때마다

Spring Context를 재시작

 

Environment가 변경되는 조건

- 테스트 코드에서 @MockBean / @SpyBean 사용할때

- 테스트 코드에서 @TestPropetrySource 로 환경변수 변경할때

- @ConditionalOnPropetry로 테스트마다 Config가 다를때

 

제거하자!

@ConditionalOnPropetry

@TestPropetrySource

 

어떻게?

모든 Config를 Loding 한 뒤.

원하는 배치 Job Bean을 실행한다.

JPA & Spring Batch

JPA N + 1 문제란

@OneToMany 관계에서

하위 엔티티들을 Lazy Loading으로 

가져올때마다 조회 쿼리가 추가로 발생하는 이슈

해결방법

1. Join Fetch

하위 엔티티 2개 종류 이상에서

Join Fetch 사용시

MultipleBagFetchException

 

2. default_batch_fetch_size

하위 엔티티를 Loading할때

지정된 숫자만큼

상위 엔티티 Id를 Where In ()

에 넣어서 조회한다.

하위 엔티티가 1만건이면

원래는 1만건 + 1건이 실행되지만

default_batch_fetch_size:1000이면

10 + 1건만 실행된다

(1만 / 1천 = 10)

 

하지만.. 이 옵션은 

JpaPagingItemReader에서는 작동하지 않는다.

(HibernateCursorItemReader는 가능)

JpaRepository에서도 사용할 수 있는 정상 기능이다.

 

JPA Persist Writer

처음 데이터가 save가 될 때도

update 쿼리가 항상 실행 됨

Spring Batch 4.2에서 기본 옵션으로 제공하기로 함

 

이동욱 발표자님 블로그

 

기억보단 기록을

Java 백엔드, AWS 기술을 익히고 공유합니다.

jojoldu.tistory.com

 

728x90
반응형