ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring Batch
    🌱 spring/🚛 spring batch 2022. 12. 16. 00:37

    ❓배치 어플리케이션


    배치(Batch)일괄처리 라는 뜻을 가지고 있다.

    매일 전 날의 데이터를 집계해야 한다고 가정

    • 집계 과정을 어디서 수행해야 할까??
      • 웹 어플리케이션으로만 생각한다면 Tomcat + Spring MVC 를 생각한다.

    하지만 이렇게 큰 데이터를 읽고 가공 후 저장한다면 해당 서버는 CPU, I/O 등의 자원을 다 써버려서 다른 Request 처리를 못하게 된다.

     

    집계 기능은 하루에 1번 수행

    • 이를 위해 API를 구성하는 것은 낭비 ❗

     

    데이터가 너무 많아 처리 중에 실패가 나는 경우?

    • 실패한 위치부터 다시 실행할 수 있다면 얼마나 좋을까

     

    이미 집계 함수를 누군가 실행했는데 다른 누군가 또 실행시켜서 데이터가 2배가 된다면?

    • 같은 파라미터로 같은 함수를 실행할 경우 이미 실행한 적이 있다면 실패하는 기능을 지원하게 하면 얼마나 좋을까

     

    이런식으로 단발성으로 대용량의 데이터를 처리하는 어플리케이션 - 배치 어플리케이션

     

    단발성

    • 어떤 일이 단 한 번만으로 그치는 성질

     

    Spring 에서 배치 어플리케이션을 지원하는 모듈 - Spring Batch

     

    배치 어플리케이션이 만족해야할 조건

    대용량 데이터

    • 배치 어플리케이션은 대량의 데이터를 가져오거나, 전달, 계산 하는 등의 처리를 할 수 있어야 한다.

    자동화

    • 배치 어플리케이션은 심각한 문제 해결을 제외하고는 사용자 개입 없이 실행되어야 한다.

    견고성

    • 배치 어플리케이션은 잘못된 데이터를 충돌 / 중단 없이 처리할 수 있어야 한다.

    신뢰성

    • 배치 어플리케이션은 무엇이 잘못되었는지를 추적할 수 있어야 한다. (로깅 또는 알림 등)

    성능

    • 배치 어플리케이션은 지정한 시간안에 처리를 완료하거나 동시에 실행되는 다른 어플리케이션을 방해하지 않도록 수행되어야 한다.

    ❓ Spring Batch


    Spring Batch는 Spring의 특성을 그대로 가져왔다.

    • DI, AOP, 서비스 추상화 등 Spring 프레임워크의 3대 요소를 모두 사용할 수 있다.

    프로젝트 생성

    • Spring Boot 2.7.4
    • Java 11
    • Gradle

    build.gradle

    plugins {
        id 'java'
        id 'org.springframework.boot' version '2.7.4'
        id 'io.spring.dependency-management' version '1.1.0'
    }
    
    group = 'com.example'
    version = '0.0.1-SNAPSHOT'
    sourceCompatibility = '17'
    
    configurations {
        compileOnly {
            extendsFrom annotationProcessor
        }
    }
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-batch'
        implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
        implementation 'org.springframework.boot:spring-boot-starter-web'
        compileOnly 'org.projectlombok:lombok'
        runtimeOnly 'com.h2database:h2'
        runtimeOnly 'mysql:mysql-connector-java'
        annotationProcessor 'org.projectlombok:lombok'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
        testImplementation 'org.springframework.batch:spring-batch-test'
    }
    ...
    

    Simple Job 생성

    @EnableBatchProcessing

    Spring Batch 기능 활성화 어노테이션 (@EnableBatchProcessing) 을 추가

    • 선언하지 않으면 기능을 사용할 수 없다 - 필수❗
    @EnableBatchProcessing // 배치 기능 활성화
    @SpringBootApplication
    public class BatchTestApplication {
    
      public static void main(String[] args) {
        SpringApplication.run(BatchTestApplication.class, args);
      }
    
    }

     

    Job 패키지 - SimpleJobConfiguration.java

    @Slf4j
    @Configuration
    public class SimpleJobConfiguration {
    
      private final JobBuilderFactory jobBuilderFactory;
      private final StepBuilderFactory stepBuilderFactory;
    
      public SimpleJobConfiguration(
          JobBuilderFactory jobBuilderFactory,
          StepBuilderFactory stepBuilderFactory) {
        this.jobBuilderFactory = jobBuilderFactory;
        this.stepBuilderFactory = stepBuilderFactory;
      }
      
      @Bean
      public Job simpleJob() {
        return jobBuilderFactory.get("simpleJob")
            .start(simpleStep1()) // Job에서 처음 시작할 Step 설정
            .build();
      }
      
      @Bean
      public Step simpleStep1() {
        return stepBuilderFactory.get("simpleStep1")
            .tasklet((contribution, chunkContext) -> {
              log.info("======== STEP 1 ======");
              return RepeatStatus.FINISHED;
            })
            .build();
      }
      
    }
    

    @Configuration

    • Spring Batch의 모든 Job은 @Configuration 으로 등록해 사용한다.

    JobBuilderFactory

    • JobBuilder를 생성하는 팩토리 클래스 get(String name) 메서드를 제공
    • get 메서드의 인자로 들어가는 String 값이 Batch Job의 이름이 된다.
    • job의 이름은 별도로 지정하지 않고 이렇게 Builder를 통해 지정한다.

    stepBuilderFactory.get(”simpleStep1”)

    • simpleStep1 이란 이름의 Batch Step 생성
    • Builder를 통해 이름을 지정한다.

    .tasklet((contribution, chunkContext))

    • Step 안에서 수행될 기능들을 명시
    • Tasklet 은 Step 안에서 단일로 수행될 커스텀한 기능들을 선언할 때 사용
    • 위 코드에서 Batch 가 수행시 log.info() 가 출력된다.

    Batch Job을 생성하는 simpleJob 코드를 보면 simpleStep1을 품고 있다.

    Spring Batch에서 Job은 하나의 배치 작업 단위를 이야기한다.

    Job 안에는 여러 Step이 존재하고, Step 안에 Tasklet 혹은 Reader & Processor & Writer 묶음이 존재

     

    Tasklet 하나와 Reader & Processor & Wrtier 한 묶음이 같은 레벨이다.

    ⇒ Reader & Processor 가 끝나고 Tasklet으로 마무리 짓는 등으로 만들 수 없다.

    Tasklet

    • Spring MVC 의 @Component, @Bean 과 비슷한 역할
    • 개발자가 지정한 커스텀한 기능을 위한 단위

     

    main 메소드 실행

    main 메소드 실행시 Batch 가 실행된다.

     

    참고자료

    https://docs.spring.io/spring-batch/docs/current/api/org/springframework/batch/core/configuration/annotation/JobBuilderFactory.html  

    https://hororolol.tistory.com/513  

    https://jojoldu.tistory.com/324  

    https://jojoldu.tistory.com/325

    '🌱 spring > 🚛 spring batch' 카테고리의 다른 글

    Spring Batch - Chunk 지향 처리  (1) 2022.12.16
    Spring Batch - Scope  (0) 2022.12.16
    Spring Batch - Job Flow  (0) 2022.12.16
    메타데이터 테이블  (0) 2022.12.16
    MySQL 환경 - Spring Batch  (0) 2022.12.16

    댓글

Designed by Tistory.