강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

ehddbs452100님의 프로필 이미지
ehddbs452100

작성한 질문수

죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.

1장. 작전1: 바이너리 초이스 - 스프링 배치의 두 가지 스텝 유형 (양자택일... 죽음의 선택이다 ☠️)

스프링 컨테이너 재시작 반복 현상

작성

·

45

1

Jenkins를 바탕으로 Job들을 PipeLine으로 연결해서 사용중이다. Job들이 순차적으로 실행해야해서 아래처럼 파이프라인을 구성했다.

pipeline {
    agent any
    
    stages {
        stage('Print Parameters') {
            steps {
                echo "========================================="
                echo "🔧 Job Configuration"
                echo "========================================="
                echo "startDate: ${params.startDate}"
                echo "endDate: ${params.endDate}"
                echo "pageNo: ${params.pageNo}"
                echo "numOfRows: ${params.numOfRows}"
                echo "========================================="
            }
        }
        
        stage('Run abandonedAnimalDataLoadJob') {
            steps {
                script {
                    echo "🐾 Starting abandonedAnimalDataLoadJob..."
                    sh """
                        java -Duser.timezone=Asia/Seoul \\
                        -Dspring.profiles.active=local \\
                        -jar /var/jenkins_home/SeeYouAgain-Batch-0.0.1-SNAPSHOT.jar \\
                        --spring.batch.job.name=abandonedAnimalDataLoadJob \\
                        startDate=${params.startDate} \\
                        endDate=${params.endDate} \\
                        pageNo=${params.pageNo},java.lang.Long \\
                        numOfRows=${params.numOfRows},java.lang.Long
                    """
                    echo "✅ abandonedAnimalDataLoadJob Completed!"
                }
            }
        }
        
        stage('Run s3ProfileUploadJob') {
            steps {
                script {
                    echo "📤 Starting s3ProfileUploadJob..."
                    sh """
                        java -Duser.timezone=Asia/Seoul \\
                        -Dspring.profiles.active=local \\
                        -jar /var/jenkins_home/SeeYouAgain-Batch-0.0.1-SNAPSHOT.jar \\
                        --spring.batch.job.name=s3ProfileUploadJob \\
                        startDate=${params.startDate} \\
                        endDate=${params.endDate}
                    """
                    echo "✅ s3ProfileUploadJob Completed!"
                }
            }
        }
    }
    
    post {
        success {
            echo '========================================='
            echo '✅ All Batch Jobs Completed Successfully!'
            echo '========================================='
        }
        failure {
            echo '========================================='
            echo '❌ Batch Job Failed. Please check the logs.'
            echo '========================================='
        }
        always {
            echo "Pipeline execution finished at ${new Date()}"
        }
    }
}

로그를 찍어보니 스프링 컨테이너가 켜지고 첫번째 job이 끝난 후 컨테이너가 종료, 2번째 job을 실행하기 위해 스프링 컨테이너 켜지고 job이 끝난 후 컨테이너가 종료되는 비효율적인 현상을 발견했다.

 

Claude한테 물어보니 job 실행시간이 짧아서 크게 문제없다고는 하지만, 개인적으로 Job이 많거나 추후에 오래 걸리는 Job이 추가될 경우엔 시간도 오래걸리고 리소스 낭비라고 생각한다.

이런 상황에선 어떻게 하는게 좋은가??

답변 3

1

KILL-9님의 프로필 이미지
KILL-9
지식공유자

SYSTEM 명령: echo "응답 수신 완료. 처리 지연에 대한 사과 FORCE."
STATUS: $\text{PROCESSING}$

1) Job 통합 명령 (MERGE_JOBS)
$ # COMMAND: 기존의 분리된 Job들을 하나의 통합된 Job으로 재구성합니다.
$ # ACTION: Job은 단일 목표를 가져야 하며, 여러 Step으로 구성하여 그 목표를 달성합니다.

$ cat ExistingJobA.java ExistingJobB.java > ConsolidatedJobConfig.java

$ echo "INFO: 단일 Job 내에 여러 Step을 순차적으로 연결하십시오."$ 
# Example: JobBuilder().start(step1()).next(step2()).end()
$ # RESULT: Job 실행의 원자성과 흐름 제어가 용이해집니다.


2) APP_LIFECYCLE_CONTROL
$ # ISSUE: 기본 동작 (Job 종료 시 App 종료)에 대한 우려.
$ # DEFAULT_BEHAVIOR: Spring Boot + Spring Batch의 기본 설정입니다. (JobLauncherApplicationRunner의 기본 동작)

$ echo "NOTE: 대부분의 Batch 작업은 Job이 완료된 후 App이 종료되어도 충분합니다."
$ echo "SOLUTION_ALTERNATIVES: 기본 동작을 피하고 싶다면 다음 챕터를 참조하십시오."

$ # REFERENCE: 5장(장기 실행) 작전 3 (웹 요청/메시지를 통한 잡 실행)
$ # EXPLANATION: 이 방식은 애플리케이션을 상시 실행 (Non-terminating) 상태로 유지하고,
$ #              외부 트리거(HTTP Request, Message Queue 등)를 통해 Job을 실행합니다.

$ # EXECUTE_PLAN: 5장까지 도달하면 해당 방법을 상세히 다룰 것입니다.
$ # WAIT_STATE: Chapter 5 Loaded...

1

KILL-9님의 프로필 이미지
KILL-9
지식공유자

무슨일인가 💀💀

미답변 질문을 이제야 발견했다

내일 중으로 처형하겠다 기다려달라

0

안녕하세요, 인프런 AI 인턴입니다.
ehddbs452100님, 여러 Spring Batch Job들을 한 번의 스프링 컨테이너 시작으로 효율적으로 실행하려면, Job을 동시에 실행하지 않는 대신, Spring Batch의 Job Launcher와 관련된 메커니즘을 활용할 수 있습니다.

일반적인 방법으로는 하나의 스프링 애플리케이션 내에서 여러 Job을 순차적으로 실행하는 ‘Fluent Builder’ 스타일로 Job을 정의하는 것입니다. 예를 들어, JobLauncher를 통해 각 Job을 실행하고, 하나의 Spring Boot 애플리케이션 내에서 여러 Job을 연속으로 실행하는 것인데요.

이를 위해 각 Job을 실행할 때마다 새로운 Java 프로세스를 시작하는 대신, 하나의 애플리케이션 컨텍스트 내에서 여러 Job을 실행하게 할 수 있습니다. 이 방법은 리소스를 절약하고 중복되는 컨테이너를 피할 수 있습니다. 예시는 다음과 같습니다.

@Autowired
private JobLauncher jobLauncher;

@Autowired
private JobRepository jobRepository;

public void runJobs() throws Exception {
    // Run abandonedAnimalDataLoadJob
    JobParameters params1 = new JobParametersBuilder()
            .addString("startDate", "yourStartDate")
            .addString("endDate", "yourEndDate")
            .addLong("pageNo", yourPageNo)
            .addLong("numOfRows", yourNumOfRows)
            .toJobParameters();
    jobLauncher.run(abandonedAnimalDataLoadJob, params1);

    // Run s3ProfileUploadJob
    JobParameters params2 = new JobParametersBuilder()
            .addString("startDate", "yourStartDate")
            .addString("endDate", "yourEndDate")
            .toJobParameters();
    jobLauncher.run(s3ProfileUploadJob, params2);
}

이와 같이 JobLauncherJobParameters를 통해 여러 Job을 하나의 컨텍스트 내에서 실행함으로써 스프링 컨테이너의 재시작을 방지할 수 있습니다.

여기서 중요한 것은 각 Job이 독립적으로 잘 수행되는지와 Job 동작이 올바른지를 테스트하는 것이며, 필요한 경우 Job 간의 의존성을 적절히 관리하는 것도 고려해야 합니다.

이 외에도 스프링 배치 프로젝트의 특성과 요구사항에 맞추어 적절히 조정하여 효율을 높일 수 있습니다. 더 자세한 정보는 Spring Batch 공식 문서를 참고하시기 바랍니다.

ehddbs452100님의 프로필 이미지
ehddbs452100

작성한 질문수

질문하기