위 동영상을 보고 정리한 자료입니다.
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
'프로그래밍 > 우아한Tech' 카테고리의 다른 글
[우아콘2020] 배달의민족 마이크로서비스 여행기 (1) | 2021.01.27 |
---|