2.8 스케줄링 (@Scheduled)
정기 배치·통계 집계·캐시 정리처럼 주기적으로 실행해야 하는 작업은 @Scheduled로 등록할 수 있습니다.
작성 기준: Spring Boot 3.2.x
1. @EnableScheduling
@SpringBootApplication
@EnableScheduling
public class Application { ... }
2. 고정 주기 실행
@Component
public class StatsScheduler {
@Scheduled(fixedRate = 60000) // 60초마다 (이전 종료 시점과 무관)
public void collectStats() {
// 통계 수집
}
@Scheduled(fixedDelay = 60000) // 종료 후 60초 뒤 다음 실행
public void cleanup() {
// 정리 작업
}
@Scheduled(initialDelay = 10000, fixedRate = 60000) // 기동 10초 후부터 60초마다
public void sync() {
// 동기화
}
}
- fixedRate: 시작 시점 기준 간격
- fixedDelay: 이전 작업 종료 후부터 간격
- initialDelay: 첫 실행 지연 (ms)
3. Cron 표현식
복잡한 요일·시간대는 cron으로 지정합니다.
@Scheduled(cron = "0 0 2 * * ?") // 매일 새벽 2시
public void dailyReport() { ... }
@Scheduled(cron = "0 */10 * * * ?") // 10분마다
public void everyTenMinutes() { ... }
형식: 초 분 시 일 월 요일 [년]
- 요일: 0–7 (0, 7 = 일요일), MON–SUN 가능
- Spring: 6자리 (년 생략)
4. 프로파일/조건으로 스케줄 끄기
특정 환경에서만 스케줄을 돌리려면 @Profile 또는 @ConditionalOnProperty를 사용합니다.
@Component
@Profile("!test")
@ConditionalOnProperty(name = "app.scheduler.enabled", havingValue = "true", matchIfMissing = true)
public class StatsScheduler { ... }
5. 단일 인스턴스 실행 (분산 환경)
서버가 여러 대일 때 같은 작업이 중복 실행되지 않게 하려면 ShedLock 또는 DB/Redis 기반 락을 사용합니다. 스프링 기본 @Scheduled만으로는 인스턴스 간 조율이 되지 않습니다.
팁
긴 작업은 스레드 풀 크기를 TaskScheduler로 제한하고, 필요하면 @Async와 조합해 별도 스레드에서 실행하도록 구성하는 것이 좋습니다.