1. Spring Batch Job 실행 개요
- 이번 글에서는 Spring Batch에서 Job을 실행하는 방법에 대해 알아봅니다.
- Spring Batch에서 배치 작업을 실행하기 위해서는 최소한 두 가지 요소가 필요합니다.
- 실행할 Job
- Job을 시작하는 JobLauncher
- 이 두 요소는 같은 컨텍스트 내에 있을 수도 있고, 서로 다른 컨텍스트에 있을 수도 있습니다.
- 커맨드라인에서 실행하면 각 Job마다 독립된 JVM과 JobLauncher가 생성되지만, 웹 애플리케이션에서는 하나의 JobLauncher를 여러 요청이 공유하게 됩니다.
- 웹 컨테이너 환경에서는 일반적으로 하나의 JobLauncher가 여러 요청에서 공유되어 사용됩니다. 이때는 비동기 Job 실행을 위해 구성되는 것이 일반적입니다.
2. 커맨드라인에서 Job 실행하기
2.1 엔터프라이즈 스케줄러와의 연동
- 실제 운영 환경에서는 대부분 엔터프라이즈 스케줄러(cron, Autosys, Control-M 등)를 통해 배치 작업을 관리합니다.
- 이런 스케줄러들은 Quartz와 달리 Java 애플리케이션과 직접 통신하지 않고, 운영체제 프로세스 레벨에서 작업을 수행합니다.
- 따라서 스케줄러가 배치 작업을 실행하려면 다음과 같은 방법들을 사용해야 합니다.
- 셸 스크립트 (가장 일반적)
- Perl, Ruby 등의 스크립트 언어
- Ant, Maven 같은 빌드 도구
2.2 CommandLineJobRunner 사용법
- Spring Batch는 커맨드라인 실행을 위한
CommandLineJobRunner
클래스를 제공합니다. - 이 클래스는 main 메서드를 가진 진입점 역할을 하며, 다음 네 가지 작업을 수행합니다.
- ApplicationContext를 로드하여 Spring 컨테이너 구성
- 전달받은 커맨드라인 인수를 JobParameters 객체로 변환
- 지정된 Job 이름으로 실행할 Job을 찾아서 위치 확인
- Spring 컨테이너에서 JobLauncher를 가져와서 Job 실행
- 이 모든 과정이 커맨드라인에서 전달받은 인수만으로 처리되기 때문에, 별도의 복잡한 설정 없이도 배치 작업을 실행할 수 있습니다.
2.2.1 필수 인수
인수 | 설명 |
---|---|
jobPath | ApplicationContext 생성에 사용되는 XML 파일의 위치 또는 Java 설정 클래스의 완전한 이름 |
jobName | 실행할 Job의 이름 |
- CommandLineJobRunner를 사용할 때 반드시 전달해야 하는 인수는 두 개입니다.
- 이 두 인수는 순서가 중요합니다. 첫 번째가 jobPath, 두 번째가 jobName이어야 하며, 그 뒤의 모든 인수들은 JobParameters로 인식됩니다.
2.2.2 실행 예시
# Java 설정 클래스를 사용한 실행
java CommandLineJobRunner io.spring.EndOfDayJobConfiguration endOfDay schedule.date=2007-05-05,java.time.LocalDate
# identifying 파라미터와 non-identifying 파라미터 구분
java CommandLineJobRunner io.spring.EndOfDayJobConfiguration endOfDay \
schedule.date=2007-05-05,java.time.LocalDate,true \
vendor.id=123,java.lang.Long,false
- JobParameters에서 identifying 여부를 명시적으로 지정할 수 있습니다.
- 파라미터 끝에
true
또는false
를 추가하여 해당 파라미터가 Job 인스턴스를 식별하는 데 사용되는지 여부를 결정할 수 있습니다.
파라미터 구분의 중요성
Spring Batch에서는 JobParameters를 identifying과 non-identifying으로 구분합니다. Identifying 파라미터는 Job 인스턴스를 구별하는 데 사용되므로, 같은 값으로는 중복 실행이 불가능합니다. 반면 non-identifying 파라미터는 실행 로직에만 영향을 주고 중복 실행을 허용합니다. 예를 들어, 매일 실행되는 배치에서 날짜는 identifying으로, 처리 모드 같은 옵션은 non-identifying으로 설정하는 것이 일반적입니다.
2.2.3 Java 설정 예시
@Configuration
@EnableBatchProcessing
public class EndOfDayJobConfiguration {
@Bean
public Job endOfDay(JobRepository jobRepository, Step step1) {
return new JobBuilder("endOfDay", jobRepository)
.start(step1)
.build();
}
@Bean
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("step1", jobRepository)
.tasklet((contribution, chunkContext) -> null, transactionManager)
.build();
}
}
2.3 Spring Boot에서 커맨드라인 실행
- Spring Boot 애플리케이션을 커맨드라인에서 실행할 때는 별도의 CommandLineJobRunner 없이도 배치 Job을 실행할 수 있습니다.
- Spring Boot는
--
로 시작하는 커맨드라인 인수를 Environment 프로퍼티로 변환합니다. - 하지만 배치 Job에 파라미터를 전달할 때는
--
없이 일반 형식을 사용해야 합니다.
2.3.1 Spring Boot 실행 예시
# 정확한 방법: -- 없이 파라미터 전달
java -jar myapp.jar someParameter=someValue anotherParameter=anotherValue
# 혼용 예시: 서버 설정과 배치 파라미터를 함께 전달
java -jar myapp.jar --server.port=7070 someParameter=someValue
- 위의 혼용 예시에서
--server.port=7070
은 Environment 프로퍼티가 되고,someParameter=someValue
만 배치 Job에 전달됩니다. - Spring Boot에서 배치 Job에 파라미터를 전달할 때는 반드시
--
없는 형식을 사용해야 합니다.- Environment 프로퍼티(
--
로 시작)는 배치 Job에서 무시됩니다.
- Environment 프로퍼티(