여러 서버에서 같은 배치 스케줄을 실행하면 같은 시간에 모두 실행됩니다. 이 경우 동일한 작업이 중복 실행됩니다. Quartz의 클러스터링 기능을 사용하면 데이터베이스를 통해 클러스터 내에서 오직 하나의 노드만 스케줄을 실행합니다.
Quartz 클러스터는 DB에 스케줄 상태를 저장해 노드 간 조율합니다. Quartz가 제공하는 SQL 스크립트로 테이블을 생성합니다.
# quartz.properties
org.quartz.scheduler.instanceId=AUTO
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.isClustered=true
org.quartz.jobStore.clusterCheckinInterval=20000
org.quartz.jobStore.dataSource=myDB
# Spring Boot 설정
spring.quartz.job-store-type=jdbc
spring.quartz.properties.org.quartz.jobStore.isClustered=true // 클러스터링된 Quartz Camel 라우트
from("quartz2:daily-report?cron=0+0+2+*+*+?&stateful=true")
.routeId("clustered-daily-report")
.log("리포트 생성 시작 - 이 노드: ${sys.hostname}")
.to("bean:reportService?method=generateDailyReport"); stateful=true를 설정하면 Job이 DB에 영속적으로 저장됩니다. 어떤 노드가 이 시간에 살아있든 단 하나만 실행됩니다.
서버가 다운된 동안 실행되어야 했던 스케줄(미스파이어)을 어떻게 처리할지 정책을 설정합니다.
// 가장 최근 미스파이어 한 번만 실행
from("quartz2:daily?cron=0+0+9+*+*+?&misfireInstruction=MISFIRE_INSTRUCTION_FIRE_ONCE_NOW")
// 미스파이어 무시 (다음 정규 실행까지 대기)
from("quartz2:daily?cron=0+0+9+*+*+?&misfireInstruction=MISFIRE_INSTRUCTION_DO_NOTHING") 관리자 UI에서 스케줄을 수정하면 클러스터 전체에 즉시 반영됩니다.
// Quartz Scheduler에서 직접 Job 추가/수정
@Autowired
private SchedulerFactory schedulerFactory;
public void updateSchedule(String jobName, String newCron) throws Exception {
Scheduler scheduler = schedulerFactory.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(jobName);
Trigger newTrigger = TriggerBuilder.newTrigger()
.withIdentity(triggerKey)
.withSchedule(CronScheduleBuilder.cronSchedule(newCron))
.build();
scheduler.rescheduleJob(triggerKey, newTrigger);
} 구글·IBM·삼성이 AI를 이유로 대규모 감원을 시작했습니다. 맥킨지·골드만삭스·옥스퍼드 연구 데이터로 보는 직종별 AI 대체 타임라인과 살아남는…
SKT 유심 해킹 2,300만 명, 다크웹 개인정보 거래 실태까지. 내 정보 유출 여부 즉시 확인하는…
하드웨어 스펙 경쟁은 끝났습니다. AI 생태계, 프리미엄 수익, 중국 변수까지. 2025년 삼성 vs 애플 진짜…
전 세계 검색 92%를 장악한 구글의 왕좌가 흔들리기 시작했습니다. AI 검색이 구글을 집어삼키는 속도와 진짜…