ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring Batch의 개념과 개발 환경 세팅
    SpringBatch 2024. 1. 28. 18:29

    0. 개념

    Batch

    Batch 작업이란, 데이터를 실시간으로 처리하는게 아니라, 일괄적으로 모아서 처리하는 작업을 의미한다.

    하루동안 쌓인 데이터를 배치작업을 통해 특정 시간에 한 번에 처리하는 경우가 이에 해당한다.

    은행의 정산작업과 같은 업무에서 이런 일괄처리를 수행하게 되며 사용자에게 빠른 응답이 필요하지 않은 서비스에 적용할 수 있다.

     

    일반적인 배치 프로그램의 종류는 다음과 같다.

    • 데이터베이스, 파일, queue로부터 다량의 자료 읽기
    • 어떤 방식으로 데이터를 처리하기
    • 수정된 형태로 데이터를 다시 작성하기

    특정 시간(실행 시작~끝)이후에는 자원을 거의 소비하지 않는 것이 특징이며 이전까지 C 언어를 베이스로 개발되는 것이 대다수였음.

     

    Spring Batch

    스프링 배치는 간단하게 말하자면 Java 기반의 배치 프로세스를 위한 프레임워크이다.

    기본 배치 반복을 자동화하여 일반적으로 사용자와 상호 작용없이 오프라인 환경에서도 유사한 트랜잭션을 세트로 처리 할 수 있는 기능을 제공한다. 배치 작업은 대부분의 IT 프로젝트의 일부이며 Spring Batch는 엔터프라이즈 규모의 강력한 솔루션을 제공하는 유일한 오픈 소스 프레임워크이다.

     

     

    구조

     

    어플리케이션은 개발자가 스프링 배치를 사용하여 작성한 모든 배치 잡과 커스텀 코드를 포함하고 있다.

     

    배치 코어는 배치 작업을 시작하고 제어하는데 필요한 코어 런타임 클래스를 포함한다(JobLauncher, Job, Step의 구현체 등).

    작성된 배치코드에서 import 문을 보면 "import org.springframework.batch.core" 로 시작하는 것들이 많은데 그 항목들을 보면 위의 내용을 확인할 수 있다.

    어플리케이션과 코어는 모두 공통 인프라 위에 구축된다.

     

    배치 인프라는 어플리케이션 개발자(ItemReader, ItemWriter와 같은 reader나 writer)와 코어 프레임워크(자체 라이브러리인 재시도(retry))에 의해 사용되는 공통 reader, writer, 서비스(e.g. Retry Template)를 포함한다.

     

     

    위의 다이어그램은 수십 년 동안 사용된 batch reference architecture의 단순화된 버전이며 또한 스프링 배치의 도메인 언어를 구성하는 주요 개념을 강조한다.

    ❗️하나의 Job에는 하나 혹은 여러 Step이 있으며, 각 Step에는 정확히 하나의 ItemReader, ItemProcessor, ItemWriter가 있다. job은 JobLauncher로 시작되고 현재실행 중인 프로세스에 대한 메타 데이터를 JobRepository에 저장해야한다.

     

     

     

    Job

    Job은 (단순하게는) Step 인스턴스를 위한 컨테이너이다. 논리적으로 하나의 흐름에 속하는 여러 스탭을 결합하고 재시작 가능성과 같은 모든 단계에 걸쳐 전체 범위의 속성을 구성할 수 있다.

     

    Job configuration에는 다음이 포함된다.
    - Job의 간단한 이름
    - Step Instance의 정의 및 순서
    - Job을 다시 시작할 수 있는지에 대한 여부
    - Job 인터페이스의 기본적인 간단한 구현체는 SimpleJob 클래스의 형태로 제공되며 Job 위에 일부 표준 기능을 생성한다. 

     

     

    Step

    Step은 배치 Job의 독립적인 순차 phase를 캡슐화하는 도메인 오브젝트이다. 

    따라서 모든 Job은 하나 혹은 그 이상의 Step으로 구성된다. 

    Step은 실제 배치 프로세싱을 정의하고 제어하는데 필요한 모든 정보를 가지고 있다.

     

    Step의 구성방식

    • Step 구성방식 1. Tasklet
    @Bean
    public Job taskletJob(JobRepository jobRepository, Step deleteFilesInDir) {
    	return new JobBuilder("taskletJob", jobRepository)
    				.start(deleteFilesInDir)
    				.build();
    }
    
    @Bean
    public Step deleteFilesInDir(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
    	return new StepBuilder("deleteFilesInDir", jobRepository)
    				.tasklet(fileDeletingTasklet(), transactionManager)
    				.build();
    }
    
    @Bean
    public FileDeletingTasklet fileDeletingTasklet() {
    	FileDeletingTasklet tasklet = new FileDeletingTasklet();
    
    	tasklet.setDirectoryResource(new FileSystemResource("target/test-outputs/test-dir"));
    
    	return tasklet;
    }

     

    • Step 구성방식 2. Chunk

    //위의 이미지랑은 상이한 코드임.
    @Bean
    public Job ioSampleJob(JobRepository jobRepository, Step step1) {
    	return new JobBuilder("ioSampleJob", jobRepository)
    				.start(step1)
    				.build();
    }
    
    @Bean
    public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
    	return new StepBuilder("step1", jobRepository)
    				.<String, String>chunk(2, transactionManager)
    				.reader(fooReader())
    				.processor(fooProcessor())
    				.writer(compositeItemWriter())
    				.stream(barWriter())
    				.build();
    }
    
    @Bean
    public CustomCompositeItemWriter compositeItemWriter() {
    
    	CustomCompositeItemWriter writer = new CustomCompositeItemWriter();
    
    	writer.setDelegate(barWriter());
    
    	return writer;
    }
    
    @Bean
    public BarWriter barWriter() {
    	return new BarWriter();
    }

     

    Tasklet vs Chunk

    Tasklet
    : 한 가지 이상의 CRUD가 발생(=비즈니스 로직)하는 task에 대해 일괄적으로 처리하는 경우, 채택한다. (복잡한 로직을 수행해야 하는 job일 경우, 채택)

    Chunk
    : chunk 단위로 처리할 모든 record를 쭉 읽어들인 후, 모두 읽어들이는데 성공하면 한번에 Write하는 방식 (대용량 데이터에 대해 단순 처리할 경우, 채택)

     

     

    Step의 흐름 제어

    • 순차적 흐름

    @Bean
    public Job job(JobRepository jobRepository, Step stepA, Step stepB, Step stepC) {
    	return new JobBuilder("job", jobRepository)
    				.start(stepA)
    				.next(stepB)
    				.next(stepC)
    				.build();
    }

     

    • 조건부 흐름

    @Bean
    public Job job(JobRepository jobRepository, Step stepA, Step stepB, Step stepC) {
    	return new JobBuilder("job", jobRepository)
    				.start(stepA)
    				.on("*").to(stepB)
    				.from(stepA).on("FAILED").to(stepC)
    				.end()
    				.build();
    }

     


    1. 프로젝트 구성 및 생성

    유료 버전의 IntelliJ를 사용한다면 프로젝트 생성 시

    아래에서 처럼 Spring Initializr 로 바로 생성 가능하다.

    IntelliJ IDEA 유료버전의 Spring Initializr 를 사용하여 프로젝트를 생성하는 화면

     

     

    Community Edition 사용 시엔 그런 기능을 제공하지 않기에 별 수 없이 

    https://start.spring.io/에서 프로젝트를 생성해서 import 해야한다.

     

    위의 사진처럼 설정된 프로젝트 생성 링크:

    https://start.spring.io/#!type=gradle-project&language=java&platformVersion=3.1.8&packaging=jar&jvmVersion=17&groupId=com.example&artifactId=SpringBatchTutorial&name=SpringBatchTutorial&description=First%20Spring%20Batch%20&packageName=com.example.SpringBatchTutorial&dependencies=batch,jdbc,mysql,data-jpa,configuration-processor,lombok

     

     

    Project 생성 시 가장 먼저 고르는 저 Project 항목의 Gradle 과 Maven은 빌드 지원 도구이다.

     

    gradle이 maven 보다 늦게 나온 도구로, 얼마 전 까지만 해도 이래 저래 불편하다며 Major로 사용되진 않았는데

    요즘엔 maven을 제끼고 다수가 사용하는 빌드 도구가 되어 버렸다. 

    간단하게 특징을 보자면 아래와 같다.

     

    maven은 여러가지 라이브러리를 pom.xml로 관리를 한다
    상속 구조로 되어있다
    하지만 가독성이 떨어지고 맞춤화된 로직 실행이 어렵다

    gradle은 설정 주입 방식이다
    스크립트 언어로 되어있어 가독성이 좋다
    maven보다 100배 정도 빠르다
    [출처] 개인프로젝트 : build system(maven, gradle)|작성자 지수깡

     

    https://blog.naver.com/h970303/223277232548

     

    Maven 과 Gradle

    프로젝트를 진행할때 여러가지 기능 구현을 위해 의존성 라이브러리를 추가해야하는 경우가 많다. 추가하는...

    blog.naver.com

     

     

Designed by Tistory.