팀 내 프로젝트로 배치 프로그램을 개발하게 되었다. 이 프로그램은 주기적으로 API 로그를 수집하고, 응답 시간이 일정 시간을 초과하는 등의 조건을 만족할 경우 Slack을 통해 알람을 발송하는 기능을 수행한다.
해당 프로그램은 쿠버네티스 환경에서 동작하며, 3개의 Pod이 실행되는 서비스에 배포되었다. 그러나 다중 인스턴스 환경에서 배치 프로그램을 실행하면 인스턴스 개수만큼 중복 실행될 위험이 있다. 이를 방지하기 위해 ShedLock을 도입하게 되었다.
프로그램은 매일 일정 시각에 정상 동작 한다는 로그를 남긴다
shedlock 적용 전에는 아래 사진처럼 동일한 로그가 pod 수만큼 3번 남는 것을 볼 수 있다. 3개의 인스턴스에서 모두 배치프로그램이 실행되는 것이다

ShedLock은 다중 인스턴스 환경에서 동일한 배치 작업이 중복 실행되지 않도록 분산 락(distributed lock) 을 제공하는 라이브러리
예를 들어, 다중 인스턴스 환경에서는, 특정 배치 작업이 모든 인스턴스에서 동시에 실행될 수 있다.
ShedLock을 사용하면 하나의 인스턴스에서만 배치 작업이 실행되도록 할 수 있다.
작동 원리
// maven
<!-- shedlock-->
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-spring</artifactId>
<version>4.44.0</version>
</dependency>
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-mongo</artifactId>
<version>4.44.0</version>
</dependency>
@Configuration
public class MongoConfig extends AbstractMongoClientConfiguration {
@Bean
@Override
public MongoClient mongoClient() {
// MongoDB 연결을 위한 MongoClient 인스턴스 생성
}
@Configuration
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "60s")
public class SchedulerConfig {
@Value("${spring.data.mongodb.database}")
private String database;
@Bean
public LockProvider lockProvider(MongoClient mongoClient) {
return new MongoLockProvider(mongoClient.getDatabase(database));
}
}
@Scheduled(cron = "0 0 0/1 * * *")
// shedlock 설정 annotation 추가
@SchedulerLock(name = "processor", lockAtLeastFor = "120s", lockAtMostFor = "120s")
void process() {
// do something
}
shedlock을 적용하면 lock 정보가 아래 사진처럼 내가 지정한 DB에 저장된다

shedlock 적용 후 배치프로그램은 아래 사진처럼 로그가 각각 한번씩만 남는 것을 볼 수 있다

좋은글 잘보고 갑니다