쵼쥬 2023. 3. 10. 00:06

프로젝트 구성 및 의존성 설정

Lombok도 추가

implementation 'org.projectlombok:lombok'

 

스프링 배치 활성화

EnableBatchProcessing과 DefaultBatchConfiguration 둘 다  Spring boot 3 부터는 사용하지 않아도 자동 활성화된다.

 

@EnableBatchProcessing

  • 총 4개의 설정 클래스를 실행시키며 스프링 배치의 모든 초기화 및 실행 구성이 이루어진다
  • 스프링 부트 배치의 자동 설정 클래스가 실행됨으로 빈으로 등록된 모든 Job 을 검색해서 초기화와 동시에 Job 을 수행하도록 구성됨
DefaultBatchConfiguration 추가
@EnableBatchProcessing가 JobRepository, JobLauncher, StepScope, JobScope 등의 Bean을 등록하고 마법을 부리는 것을 대신할 Configuration class가 추가되었다.
Spring Boot 3.x 부터는 DefaultBatchConfiguration를  Config 클래스에 상속하여 사용하면 된다.
package com.example.springbatch;

import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
// @EnableBatchProcessing
public class SpringBatchApplication {

   public static void main(String[] args) {
      SpringApplication.run(SpringBatchApplication.class, args);
   }

}

 

스프링 배치 초기화 설정 클래스

1. BatchAutoConfiguration
  • 스프링 배치가 초기화 될 때 자동으로 실행되는 설정 클래스
  • Job 을 수행하는 JobLauncherApplicationRunner 빈을 생성

 

2. SimpleBatchConfiguration
  • JobBuilderFactory 와 StepBuilderFactory 생성
  • 스프링 배치의 주요 구성 요소 생성 - 프록시 객체로 생성됨
 
3. BatchConfigurerConfiguration
  • BasicBatchConfigurer
    • SimpleBatchConfiguration 에서 생성한 프록시 객체의 실제 대상 객체를 생성하는 설정 클래스
    • 빈으로 의존성 주입 받아서 주요 객체들을 참조해서 사용할 수 있다
  • JpaBatchConfigurer
    • JPA 관련 객체를 생성하는 설정 클래스
  • 사용자 정의 BatchConfigurer 인터페이스를 구현하여 사용할 수 있음

https://ojt90902.tistory.com/760

 

Spring Batch : Spring Batch 시작, @EnableBatchProcessing

@EnableBatchProcessing 스프링 Batch를 실행하기 위해서는 스프링부트 메인 클래스에 @EnbableBatchPrcoessing을 설정해줘야한다. 그렇다면 @EnableBatchProcessing 어노테이션을 달면 어떤 일이 일어날까? @EnableBatch

ojt90902.tistory.com

 

Hello Spring Batch 시작

package com.example.springbatch;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.job.builder.SimpleJobBuilder;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;

import lombok.RequiredArgsConstructor;

@Configuration
@RequiredArgsConstructor
public class HelloJobConfiguration {

   /*
   Spring Batch 5 부터 사용변경
   

   private final JobBuilderFactory jobBuilderFactory;
   private final StepBuilderFactory stepBuilderFactory;

   @Bean
   public Job helloJob() {
      return jobBuilderFactory.get("helloJob").start(helloStep()).build();
   }

   @Bean
   public Step helloStep() {
      return stepBuilderFactory.get("helloStep")
         .tasklet(((contribution, chunkContext) -> {
            System.out.println("Hello Spring Batch");
            return RepeatStatus.FINISHED;
         })).build();
   }
    */

   @Bean
   public Job helloJob(JobRepository jobRepository, Step step) {
      return new JobBuilder("helloJob", jobRepository)
         .incrementer(new RunIdIncrementer())
         .flow(step)
         .end()
         .build();
   }

   @Bean
   public Step helloStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
      return new StepBuilder("helloStep", jobRepository)
         .tasklet((contribution, chunkContext) -> {
            System.out.println("Hello Spring Batch");
            return RepeatStatus.FINISHED;
         }, transactionManager)
         .build();
   }

}
사용자가 문서를 읽어 인지하지 않는 한 Builder에서 JobRepository가 생성되고 설정된다는 사실을 숨기고 있다.그래서 아래와 같이 JobRepository과 PlatformTransactionManager를 명시적으로 제공하는 방식을 사용하길 권장한다.

https://jojoldu.tistory.com/328

 

4. Spring Batch 가이드 - Spring Batch Job Flow

자 이번 시간부터 본격적으로 실전에서 사용할 수 있는 Spring Batch 내용들을 배워보겠습니다. 작업한 모든 코드는 Github에 있으니 참고하시면 됩니다. 앞서 Spring Batch의 Job을 구성하는데는 Step이

jojoldu.tistory.com

 

Job 구동 -> Step을 실행 -> Tasklet 실행

Spring Batch에서는 Job이 있습니다. Job은 여러개의 Step으로 구성되고, Step 은 Tasklet(기능) 으로 구성됩니다. 배치 작업 하나가 Job에 해당 됩니다.

 

 

 

DB 스키마 생성 및 이해

스프링 배치 메타 데이터
  • 스프링 배치의 실행 및 관리를 위한 목적으로 여러 도메인들(Job, Step, JobParameters..) 의 정보들을 저장, 업데이트, 조회할 수 있는 스키마 제공
  • 과거, 현재의 실행에 대한 세세한 정보, 실행에 대한 성공과 실패 여부 등을 일목요연하게 관리함으로서 배치운용에 있어 리스크 발생시 빠른 대처 가능
  • DB 와 연동할 경우 필수적으로 메타 테이블이 생성 되어야 함
 
DB 스키마 제공
  • 파일 위치 : /org/springframework/batch/core/schema-*.sql
  • DB 유형별로 제공
 
스키마 생성 설정
  • 수동 생성 – 쿼리 복사 후 직접 실행
  • 자동 생성 - spring.batch.jdbc.initialize-schema 설정
    • ALWAYS
      • 스크립트 항상 실행
      • RDBMS 설정이 되어 있을 경우 내장 DB 보다 우선적으로 실행
    • EMBEDDED : 내장 DB일 때만 실행되며 스키마가 자동 생성됨, 기본값
    • NEVER
      • 스크립트 항상 실행 안함
      • 내장 DB 일경우 스크립트가 생성이 안되기 때문에 오류 발생
      • 운영에서 수동으로 스크립트 생성 후 설정하는 것을 권장

 

 

application.yml - mysql, h2 Setting

spring:
  profiles:
    active: mysql # mysql, local 중 선택해서 실행

---
spring:
  config:
    activate:
      on-profile: local
  datasource:
    url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
    username: sa
    password:
    driver-class-name: org.h2.Driver

---
spring:
  config:
    activate:
      on-profile: mysql
  datasource:
    url: jdbc:mysql://localhost:3306/springbatch?useUnicode=treu&characterEncoding=utf8
    username: root
    password: 1234
    driver-class-name: com.mysql.cj.jdbc.Driver

  # Batch 설정
  batch:
    jdbc:
      initialize-schema: always

 

DB 스키마

 

Job  관련 테이블

BATCH_JOB_INSTANCE

 

  • Job 이 실행될 때 JobInstance 정보가 저장되며 job_name과 job_key를 키로 하여 하나의 데이터가 저장
  • 동일한 job_name 과 job_key 로 중복 저장될 수 없다
JOB_INSTANCE_ID 고유하게 식별할 수 있는 기본 키
VERSION 업데이트 될 때 마다 1씩 증가
JOB_NAME Job 을 구성할 때 부여하는 Job 의 이름
JOB_KEY job_name jobParameter  합쳐 해싱한 값을 저장

 

BATCH_JOB_EXECUTION

 

  • job 의 실행정보가 저장되며 Job 생성, 시작, 종료 시간,  실행상태, 메시지 등을 관리
JOB_EXECUTION_ID JobExecution 을 고유하게 식별할 수 있는 기본 키, JOB_INSTANCE 와 일대 다 관계
VERSION 업데이트 될 때마다 1씩 증가
JOB_INSTANCE_ID JOB_INSTANCE 의 키 저장
CREATE_TIME 실행(Execution)이 생성된 시점을 TimeStamp 형식으로 기록
START_TIME 실행(Execution)이 시작된 시점을 TimeStamp 형식으로 기록
END_TIME 실행이 종료된 시점을 TimeStamp으로 기록하며 Job 실행 도중 오류가 발생해서 Job 이 중단된 경우 값이 저장되지 않을 수 있음
STATUS 실행 상태 (BatchStatus)를 저장 (COMPLETED, FAILED, STOPPED…)
EXIT_CODE 실행 종료코드(ExitStatus) 를 저장 (COMPLETED, FAILED…)
EXIT_MESSAGE Status가 실패일 경우 실패 원인 등의 내용을 저장
LAST_UPDATED 마지막 실행(Execution) 시점을 TimeStamp 형식으로 기록

 

BATCH_JOB_EXECUTION_PARAMS

 

  • Job과 함께 실행되는 JobParameter 정보를 저장
JOB_EXECUTION_ID JobExecution 식별 키, JOB_EXECUTION 과는 일대다 관계
TYPE_CD STRING, LONG, DATE, DUBLE 타입정보
KEY_NAME 파라미터 키 값
STRING_VAL 파라미터 문자 
DATE_VAL 파라미터 날짜 
LONG_VAL 파라미터 LONG 
DOUBLE_VAL 파라미터 DOUBLE 
IDENTIFYING 식별여부 (TRUE, FALSE)

 

 

BATCH_JOB_EXECUTION_CONTEXT

 

 

  • Job 의 실행동안 여러가지 상태정보, 공유 데이터를 직렬화 (Json 형식) 해서 저장
  • Step 간 서로 공유 가능함
JOB_EXECUTION_ID JobExecution 식별 키, JOB_EXECUTION 마다 각 생성
SHORT_CONTEXT JOB  실행 상태정보, 공유데이터 등의 정보를 문자열로 저장
SERIALIZED_CONTEXT 직렬화(serialized)된 전체 컨텍스트

 

Step  관련 테이블

BATCH_STEP_EXECUTION

 

  • Step 의 실행정보가 저장되며 생성, 시작, 종료 시간,  실행상태, 메시지 등을 관리
STEP_EXECUTION_ID Step  실행정보를 고유하게 식별할 수 있는 기본 키
VERSION 업데이트 될 때마다 1씩 증가
STEP_NAME Step 을 구성할 때 부여하는 Step 이름
JOB_EXECUTION_ID JobExecution 기본키, JobExecution 과는 일대 다 관계
START_TIME 실행(Execution)이 시작된 시점을 TimeStamp 형식으로 기록
END_TIME 실행이 종료된 시점을 TimeStamp 으로 기록하며 Job 실행 도중 오류가 발생해서 Job 이 중단된 경우 값이 저장되지 않을 수 있음
STATUS 실행 상태 (BatchStatus)를 저장 (COMPLETED, FAILED, STOPPED…)
COMMIT_COUNT 트랜잭션 당 커밋되는 수를 기록
READ_COUNT 실행시점에 Read Item 수를 기록
FILTER_COUNT 실행도중 필터링된 Item 수를 기록
WRITE_COUNT 실행도중 저장되고 커밋된 Item 수를 기록
READ_SKIP_COUNT 실행도중 Read Skip 된 Item 수를 기록
WRITE_SKIP_COUNT 실행도중 write Skip된 Item 수를 기록
PROCESS_SKIP_COUNT 실행도중 Process Skip 된 Item 수를 기록
ROLLBACK_COUNT 실행도중 rollback이 일어난 수를 기록
EXIT_CODE 실행 종료코드(ExitStatus) 를 저장 (COMPLETED, FAILED…)
EXIT_MESSAGE Status가 실패일 경우 실패 원인 등의 내용을 저장
LAST_UPDATED 마지막 실행(Execution) 시점을 TimeStamp 형식으로 기록

 

BATCH_STEP_EXECUTION_CONTEXT

  • Step 의 실행동안 여러가지 상태정보, 공유 데이터를 직렬화 (Json 형식) 해서 저장
  • Step 별로 저장되며 Step 간 서로 공유할 수 없음 (BATCH_JOB_EXECUTION_CONTEXT 차이)
STEP_EXECUTION_ID StepExecution 식별 키, STEP_EXECUTION 마다 각 생성
SHORT_CONTEXT STEP  실행 상태정보, 공유데이터 등의 정보를 문자열로 저장
SERIALIZED_CONTEXT 직렬화(serialized)된 전체 컨텍스트