2022년 하반기에 SpringBoot 3.0 이 릴리즈 되었고 많은 변화가 있었습니다. (내용)
기본 Java 버전이 17 으로 올라갔고, SpringBatch 버전도 5 로 올라갔습니다.
이번 시간에는 SpringBatch 5 를 적용한 사례를 공유하고자 합니다.
What's New in Spring Batch 5
SpringBatch 의존성 주입
SpringBatch 와 h2 데이터베이스 의존성을 주입한다.
implementation("org.springframework.boot:spring-boot-starter-batch")
implementation("com.h2database:h2")
SpringBatchApplication 생성
배치잡은 실행이 되고 자동으로 종료되어야 하니 exitProcess 를 실행시켜준다.
@SpringBootApplication
class CryptoLabsBatchApplication
fun main(args: Array<String>) {
val runApplication = runApplication<CryptoLabsBatchApplication>(*args)
exitProcess(SpringApplication.exit(runApplication))
}
SpringBatch 설정 (Config.)
@BatchDataSource 어노테이션으로 배치용 DataSource 를 설정해주고, 데이터베이스는 H2 를 사용한다.
(이 설정 부분을 놓쳐서 계속 배치잡이 정상적으로 동작하지 않았었다.)
@Configuration
class BatchJobConfig {
@Bean("batchDataSource")
@BatchDataSource
fun batchDataSource(): DataSource = EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2)
.addScript("/org/springframework/batch/core/schema-h2.sql")
.generateUniqueName(true).build()
}
특정 스프링배치 잡만 실행시키기 위해서는 아래처럼 application.yml 파일도 설정해줘야 한다. 만약 해주지 않을 경우에는 등록된 모든 배치 잡이 실행되게 된다.
# application.yml
spring:
batch:
job:
names: ${job.name:NONE}
배치잡 생성 (Batch Configuration)
이 배치잡의 역할은 특정 UseCase 를 호출하는 단순 Tasklet 이다.
@Configuration
class FetchUpbitCandleBatchConfiguration(
private val sendCandleMessageUseCase: SendCandleMessageUseCase,
) {
private val logger = logger()
companion object {
const val JOB_NAME = "fetchUpbitCandleBatchJob"
const val STEP_NAME = "${JOB_NAME}_step"
}
@Bean
fun job(jobRepository: JobRepository, platformTransactionManager: PlatformTransactionManager): Job {
logger.info { "$JOB_NAME 을 시작합니다." }
return JobBuilder(JOB_NAME, jobRepository)
.preventRestart()
.start(step(jobRepository, platformTransactionManager))
.incrementer(RunIdIncrementer())
.build()
}
@Bean
fun step(jobRepository: JobRepository, platformTransactionManager: PlatformTransactionManager): Step {
return StepBuilder(STEP_NAME, jobRepository)
.tasklet({ _, _ ->
val command = UpbitMinuteCandleSearchCommand(MarketPair.KRW_BTC.value, 1, 10);
sendCandleMessageUseCase.publishMinuteCandle(command)
RepeatStatus.FINISHED
}, platformTransactionManager)
.build()
}
}
Job 과 Step 을 각각 스프링 빈으로 등록해준다.
JobRepository 와 PlatformTransactionManager 를 주입받을 수 있도록 한다.
어려웠던 점
SpringBatch 4 와 5 버전의 큰 차이점 중 하나는 TransactionManager 를 명시적으로 사용하는지에 대한 유무이다. SpringBatch 4 버전에서는 JobBuilderFactory 와 StepBuilderFactory 를 사용해서 따로 TransactionManager 를 작성하지 않아도 알아서 동작했던 반면, SpringBatch 5 에서는 명시적으로 사용해야 하는 것 같다. 관련 내용
이런 부분들을 쉽게 풀어보고자 SpringBatch 5 에서는 DefaultBatchConfiguration 을 사용하라고 안내하는데, 작동이 잘 되듯 하면서 잘 안되는 부분들이 있었다. Job, Step 은 기대했던 것처럼 정상 동작했지만 Tasklet 이 실행되지 않았다.
구글에 내용을 찾아보니 비슷한 경험을 한 글들이 있었고, 해당 글에서는 DefaultBatchConfiguration 을 따로 사용하지 않았다. 관련 내용 1, 관련 내용 2
결국 나도 DefaultBatchConfiguration 을 사용하지 않고, @BatchDataSource 등 별도로 설정해서 해결했다.
느낀 점
사실 아직 뭐가 더 좋아졌는지 체감이 안되어서 SpringBatch 5 를 꼭 써야겠다! 라는 생각은 잘 안든다. 새로운 버전을 사용해본다 정도..?
'스프링 > 만들면서 배우는 실무 백엔드 개발' 카테고리의 다른 글
15. 실시간 데이터 저장 파이프라인 구축하기 (feat. 카프카 활용기) (0) | 2023.08.20 |
---|---|
14. GitHub Action 에서 스프링 배치 실행하기 (0) | 2023.08.08 |
12. SpringBoot 에서 AOP 적용하기 (Kotlin) (0) | 2023.05.04 |
11. Jacoco + Gradle.kts 로 테스트 커버리지 확인하기 (feat. SonarQube) (0) | 2023.04.07 |
10. ArchUnit 으로 아키텍쳐 검사하기 (0) | 2023.04.05 |
댓글