요약
- Scheduler job은 처리 시간을 반드시 고려해야 한다
- 이전 job이 끝나기 전에 다음 스케줄이 실행되면 중복 처리, 리소스 경합이 발생한다
본문
Job 중첩 실행 문제
- 이전 job이 안 끝났는데 다음 스케줄이 트리거되면 문제 발생
- 동일 데이터 중복 처리
- DB 커넥션, 메모리 등 리소스 경합
해결 방법
Lock 기반
- 분산 락(Redis, DB lock)으로 중복 실행 방지
- job 시작 시 락 획득, 종료 시 해제
DB Unique Constraint로 유저별 단일 Job 보장
(user_id, status)unique constraint +started_at컬럼으로 timeout 관리- 이력 보존이 필요하면 Partial Index 활용
- 좀비 레코드 방지: 주기적으로
started_at이 오래된 running 상태 정리 필요
프레임워크 설정
- Quartz:
@DisallowConcurrentExecution - Spring:
fixedDelayvsfixedRate구분fixedRate: 이전 실행과 무관하게 고정 간격으로 실행fixedDelay: 이전 실행 완료 후 간격을 두고 실행
- RQ (Redis Queue):
job_timeout: job 최대 실행 시간 설정 (기본 180초)ttl: 결과 보관 시간failure_ttl: 실패한 job 보관 시간depends_on: job 간 의존성 설정으로 순차 실행 보장- RQ-Scheduler:
interval기반 반복 실행 시 이전 job 완료 여부 체크 안 함 → 별도 락 필요
상태 체크
- job 시작 전 이전 실행 상태 확인
- 실행 중이면 skip 또는 대기
스케줄 간격 설정
- 평균 처리 시간 + 버퍼를 고려해서 간격 설정
- 처리량이 가변적이면
fixedDelay방식이 안전
타임아웃 설정
- 무한 대기 방지를 위한 job 타임아웃 필수
- 타임아웃 발생 시 알림 + 후속 처리 로직 필요