백엔드 시스템에서는 정해진 주기마다 특정 작업을 자동으로 수행해야 하는 경우가 많습니다. 예를 들어 매일 자정에 통계 데이터를 집계하거나, 주기적으로 캐시를 갱신하는 등의 작업이 이에 해당됩니다. Spring에서는 이러한 정기 작업을 @Scheduled 애노테이션으로 간단하게 구현할 수 있습니다.
Spring Scheduler란?
Spring Scheduler는 스프링 프레임워크에서 제공하는 내장 스케줄링 기능으로, 별도의 외부 라이브러리 없이도 주기적인 작업을 손쉽게 수행할 수 있도록 지원합니다. 내부적으로는 TaskScheduler 인터페이스와 ThreadPoolTaskScheduler 구현체를 기반으로 동작합니다.
즉, @Scheduled 애노테이션만 추가하면 복잡한 스케줄 관리 코드를 작성할 필요 없이 주기적 작업을 수행할 수 있습니다.
@Scheduled 기본 사용법
스케줄링 기능을 사용하려면 우선 @EnableScheduling 애노테이션을 활성화해야 합니다. 이후 스케줄링할 메서드에 @Scheduled를 지정합니다.
1. 기본 설정
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@EnableScheduling
public class SampleScheduler {
// 5초마다 실행
@Scheduled(fixedRate = 5000)
public void runEveryFiveSeconds() {
System.out.println("5초마다 실행되는 작업: " + System.currentTimeMillis());
}
}
위 예제는 애플리케이션이 실행된 이후, 5초마다 runEveryFiveSeconds() 메서드를 자동으로 실행합니다.
@Scheduled 속성 설명
Spring의 @Scheduled는 다음과 같은 주요 속성을 제공합니다:
- fixedRate: 메서드 실행 시작 시점으로부터 고정 주기로 실행
- fixedDelay: 이전 실행이 끝난 시점으로부터 일정 시간 후 실행
- initialDelay: 첫 실행 전 지연 시간 설정
- cron: 크론 표현식 기반 스케줄링 지원
2. fixedDelay vs fixedRate 차이
두 옵션의 차이는 다음 예제를 통해 쉽게 이해할 수 있습니다.
// fixedRate: 메서드 실행 시작 기준으로 3초마다 실행
@Scheduled(fixedRate = 3000)
public void rateTask() throws InterruptedException {
Thread.sleep(1000);
System.out.println("fixedRate 실행: " + System.currentTimeMillis());
}
// fixedDelay: 메서드 실행 종료 후 3초 뒤 실행
@Scheduled(fixedDelay = 3000)
public void delayTask() throws InterruptedException {
Thread.sleep(1000);
System.out.println("fixedDelay 실행: " + System.currentTimeMillis());
}
즉, fixedRate는 일정 간격 유지가 목적이고, fixedDelay는 실행 완료 후 대기 시간이 필요한 작업에 적합합니다.
cron 표현식으로 스케줄 제어
Cron 표현식을 사용하면 더욱 정교한 스케줄 설정이 가능합니다. 형식은 다음과 같습니다:
초 분 시 일 월 요일
예를 들어 매일 자정에 실행하려면 다음과 같이 작성합니다.
@Scheduled(cron = "0 0 0 * * *")
public void midnightJob() {
System.out.println("매일 자정 실행");
}
Cron은 6개의 필드를 가지며, 다음과 같은 예시로 활용됩니다.
0 0/5 * * * *— 5분마다 실행0 0 9 * * MON-FRI— 평일 오전 9시 실행0 30 23 L * *— 매월 마지막 날 23시 30분 실행
ThreadPoolTaskScheduler로 병렬 스케줄링
기본적으로 @Scheduled는 단일 스레드에서 실행되므로, 여러 작업이 동시에 실행되면 지연이 발생할 수 있습니다. 이를 해결하기 위해 ThreadPoolTaskScheduler를 사용해 병렬 실행 환경을 구성할 수 있습니다.
1. Bean 설정
@Configuration
@EnableScheduling
public class SchedulerConfig {
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(5); // 동시에 실행 가능한 스레드 수
scheduler.setThreadNamePrefix("Scheduler-");
scheduler.initialize();
return scheduler;
}
}
이렇게 하면 여러 개의 스케줄 작업이 동시에 실행되어도 서로 간섭 없이 안정적으로 동작합니다.
실무에서의 활용 예시
- 매일 새벽 3시에 데이터 백업 실행
- 5분마다 캐시 리프레시
- API 데이터 동기화 작업 주기적 수행
- 특정 요일마다 통계 리포트 생성
이처럼 Scheduler는 주기적 관리 작업을 자동화하여 시스템의 안정성과 효율성을 높이는 핵심 요소입니다.
주의할 점
- 스케줄 작업은 예외 처리를 반드시 포함해야 함 (예외 미처리 시 전체 스케줄 중단 가능)
- 동일 시간대 다중 실행 방지를 위해 분산 락 (Redis Lock, DB Lock) 적용 고려
- 스케줄 중복 실행 방지를 위한 상태 관리 필수
- 운영 환경에서는 로그 남기기 및 실행 모니터링 필수
Spring Scheduler는 간단한 어노테이션 설정만으로도 주기적인 작업을 안정적으로 수행할 수 있는 강력한 도구입니다. 하지만 단순히 실행만 되는 것에 그치지 않고, 병렬 처리, 예외 제어, 로그 관리, 분산 환경 고려까지 함께 설계하는 것이 중요합니다. 실무에서는 이러한 세부 사항을 신경 쓸수록 장애에 강하고 유지보수가 쉬운 스케줄 시스템을 만들 수 있습니다.
'개발 > JAVA' 카테고리의 다른 글
| [JAVA] Spring Batch와 JPA 연동하기 — 대량 데이터 처리에서의 효율적인 영속성 관리 (0) | 2025.11.02 |
|---|---|
| [JAVA] Spring Batch 기초 — 대량 데이터 처리를 위한 실무 중심 가이드 (0) | 2025.11.01 |
| [JAVA] 로깅과 AOP를 이용한 공통 로직 처리 (0) | 2025.10.30 |
| [JAVA] Spring AOP에서 @Aspect와 @Around 어노테이션 제대로 활용하기 (0) | 2025.10.29 |
| [JAVA] Spring AOP(관점 지향 프로그래밍) 기초 완전 정복 (0) | 2025.10.28 |
