September 26, 2019
배치 애플리케이션은 도대체 무엇인지? 질문을 많이 받는다.
일반적인 웹과 무슨 차이가 있는가?
QA가 어렵다.Quartz는 스케쥴링 프레임워크이다.Spring Batch는 Batch 프레임워크이다.당연히 둘의 차이가 있다. 비교 대상 하는 것 자체가 다른 역할을 하는 프레임워크이기에 어렵다.
pagesize만큼 읽어오고, chunkSize만큼 commit한다.ChunkOrientedTasklet의 위주로 움직인다.Enum/Date(LocalDate)/LocalDateTime와 같은 경우는 형변환(String)을 해주어야 한다.JobParameter 순수 클래스를 만들어주고, @Value로 넣어줄 수 있도록 @Bean으로 만들어주고 해당 값을 실제 스텝에서 호출해서 사용하기만 함.@JobScope, @StepScope는 Lazy loading(Late Binding으로 설명해주심)이다.
Lazy Loading으로 쓴 이유는 결국 해당 스코프가 늦게 로딩 되는 걸로 이해하면 편할듯..
여러가지 중에서 어느 정도 인지도도 있고, 노하우를 쉽게 얻을 수 있는 Jenkins를 선택 한다. (혹은 Spring Cloud Data Flow를 쓰는 방식이 좋을 수 있다.)
위 정보들이 배치마다 설정을 입력 해주어야 한다.
Environment variables를 설정 할 수 있기에 해당 정보를 입력을 해주면, 모든 Job에서 사용할 수 있다.
AWS를 쓴다면, 테스트 및 빌드 후 S3에 업로드 한 뒤에, CodeDeploy로 요청을 넣어서, 스프링 배치를 배포 하게 된다.
CodeDeploy를 안쓰면, SCP를 활용한다.readlink를 활용하여, app.jar -> v1.jar / v2.jar을 보도록 한다. (배치에서는 실제 v1.jar를 보고 Batch job을 실행한다.)Batch job은 v1.jar에서 수행을 하고, 원본 파일이 새로 배포 되면, 새로운 Batch Job은 v2.jar에서 새로운 Job이 실행 된다.Jenkins Environment variables에서 설정을 하되 실행을 하는 $()는 변수로 뺄 수 없다.Batch Job이 실행 되어야 하는 경우여러 작업이 순차적으로 실행 되어야 하는 경우 Step으로 쪼개지 말고, 각 각 분리 시킨다.
new Scanner / LocalDate.noe()와 같은 경우 멱등성이 깨진다.
JobParameter로 올려서 해당 배치를 실행할 시점의 값으로 실행 할 수 있도록 한다.그럼 어떻게 오늘 일자를 yyyy-MM-dd형식으로 배치 실행에 파라미터로 넣어 줄 수 있을까? 고민
Plugin(Date Parameter)을 만듬.@ConditionalOnProperty를 활용 한다.@TestPropertySource를 활용하면, Jenkins처럼 테스트를 돌릴 수 있다.@ConditionalOnProperty가 범인인데, 스프링은 전체 테스트가 수행 될 때마다, Environment가 변화 하면, Spring Context를 재시작 한다.@MockBean, @SpyBean 사용@TestPropertySource로 환경변수 변경할 때@ConditionalOnProperty로 테스트 마다 Config가 다를때@ConditionalOnProperty, @TestPropertySource를 제거 하자.genBean()으로 Job name으로 조회 한 뒤에, 테스트 대상에 포함 시킨다.JobTestUtils로 미리 launcher를 만들어 둔 뒤에, Job Test 코드에서 해당 유틸에 Job 이름을 넣어주고 테스트를 실행 한다.@oneToMany관계에서 하위 엔티티들을 Lazy Loading으로 가져 오면, 조회 쿼리가 계속 발생
Join Fetch 사용하되 일시적인 해결 (하위 엔티티 2개 종류 이상에서 걸게 되면, Exception 발생)default_batch_fetch_size로 해결 (하이버네이트 설정)JpaPagingItemReader에서는 작동 하지 않고, HibernateCursorItemReader에서는 가능하다.JpaRepository에서도 사용할 수 있는 기능이다.PR이 리뷰 대기 상태라고 한다.entityManager.merge에서 처음 데이터가 저장 될 때도, update 쿼리가 항상 실행 됨.
persist만 하는 JpaItemWrite를 똑같이 만들어서 쓰는데, 4.2에서 릴리즈 되면 수정된 버전이 나온다.