[SpringBoot] @Scheduled를 이용한 스케줄러 구현
Spring 프레임워크에서 제공하는 @Scheduled어노테이션은 주기적으로 실행해야 하는 작업 데이터 정리, 알림 전송, 백업 등의 작업을 자동화하는 도구입니다.
이번 포스팅에서는 @Scheduled어노테이션에 대한 개념과 이를 활용한 주기적인 작업 실행 예제를 다뤄보도록 하겠습니다.
@Scheduled 란?
@Scheduled
는 Spring에서 제공하는 스케줄링 작업을 정의하는 어노테이션입니다. 이를 통해 특정 메서드를 주기적으로 실행하거나, 예약된 시간에 실행하도록 설정할 수 있습니다.- Spring에서
@Scheduled
어노테이션은 기본적으로싱글 스레드
에서 실행되며, 만약 두 개 이상의@Scheduled
작업이 정의되어 있어도, 별도의병렬 스케줄링 설정
을 하지 않으면 순차적으로 실행됩니다. 즉, 여러 작업이 동시에 실행되지 않고, 하나씩 차례로 실행되는 것입니다. @Scheduled
어노테이션을 활성화하려면 애플리케이션에@EnableScheduling
을 추가해야 합니다. 이 어노테이션을 사용하면@Scheduled
어노테이션이 붙은 메서드들이자동
으로 실행됩니다.
사용 방법
스케줄링 활성화
@EnableScheduling @SpringBootApplication public class SchedulerApplication { public static void main(String[] args) { SpringApplication.run(SchedulerApplication.class, args); } }
@Scheduled
사용을 위해 Application 클래스
에서 @EnableScheduling
을 설정합니다.
@Scheduled 어노테이션 적용
@Slf4j @Component public class SchedulerTask { @Scheduled(fixedDelay = 1000) // 1초마다 실행 public void run() { log.info("Scheduler 실행"); } }
@Component
를 사용하여 해당 스케줄러를 Spring Bean
에 등록합니다.

해당 클래스를 Bean
으로 등록 후 애플리케이션을 실행하면 설정한 시간마다 실행되는 모습을 확인할 수 있습니다.
@Scheduled 속성
@Scheduled
속성을 이용하여 스케줄 옵션을 다양하게 설정할 수 있습니다.

@Scheduled(cron = "0 0 7 * * ?") // 매일 07시에 실행 public void run() { log.info("Scheduler 실행"); }
- cron
- 크론
cron
정규표현식을 사용해 원하는 시간대나 요일에 작업을 실행합니다.
- 크론
- cron 필드
필드 명
:값의 허용 범위
:허용된 특수 문자
- 초
Seconds
:0 ~ 59
:, - * /
- 분
Minutes
:0 ~ 59
:, - * /
- 시
Hours
:0 ~ 23
:, - * /
- 일
Day
:1 ~ 31
:, - * ? / L W
- 월
Month
:1 ~ 12 또는 JAN ~ DEC
:, - * /
- 요일
Week
:0 ~ 6 또는 SUN ~ SAT
:, - * ? L #
- 특수 문자
*
: 모든 값을 의미?
: 특정한 값이 없음을 의미-
: 범위를 나타낼 때 사용 →월요일부터 수요일까지 - MON-WED
,
: 특정 값을 여러 개 나열할 때 사용 →월,수,금 - MON,WED,FRI
/
: 시작 시간 /단위 →0분부터 매 5분 - 0/5
L
: 일에서 사용하면 마지막 일, 요일에서 사용하면 마지막 요일(토요일)W
: 가장 가까운 평일 →15일에서 가장 가까운 평일 - 15W
#
: 몇째 주의 무슨 요일을 표현 →2번째주 수요일 - 3#2
@Scheduled(fixedDelay = 10000) // 이전 작업 종료 후 10초 뒤 실행 public void run1() { log.info("Scheduler 실행1"); } @Scheduled(fixedDelayString = "10000") // 문자열 public void run2() { log.info("Scheduler 실행2"); }
- fixedDelay
- ms 단위
- 이전 Task의 종료 시점으로부터 정의된 시간만큼 지난 후 Task를 실행합니다.
이전 작업이 종료된 시점 기준으로 일정 시간 뒤 실행
fixedDelayString
fixedDelay와 동일하지만, property의 값을 String으로 입력합니다.
@Scheduled(fixedRate = 10000) // 10초 간격으로 실행 public void run1() { log.info("Scheduler 실행1"); } @Scheduled(fixedRateString = "10000") // 문자열 public void run2() { log.info("Scheduler 실행2"); }
- fixedRate
- ms 단위
- 이전 Task의 시작 지점으로부터 정의된 시간만큼 지난 후 Task를 실행합니다.
이전 작업이 시작된 시점 기준으로 일정 간격으로 실행
fixedRateString
fixedRate와 동일하지만, property의 값을 String으로 입력합니다.
@Scheduled(fixedRate = 10000, initialDelay = 1000) // 1초 대기 후 시작, 10초 간격 실행 public void run() { log.info("Scheduler 실행"); }
- initialDelay
- 스케줄러에서 메서드가 등록되자마자 수행하는 것이 아닌, 초기 지연시간을 설정합니다.
작업이 시작되기 전 초기 대기 시간을 설정
initialDelayString
initialDelay와 동일하지만, property의 값을 String으로 입력합니다.
- 스케줄러에서 메서드가 등록되자마자 수행하는 것이 아닌, 초기 지연시간을 설정합니다.
@Scheduled(zone = "Asia/Seoul", cron = "0 0 7 * * ?") // 타임존 서울, 매일 07시에 실행 public void run() { log.info("Scheduler 실행"); }
- zone
- time zone 설정
- default : 서버의 time zone
Thread Pool 설정

@Scheduled(zone = "Asia/Seoul", fixedDelay = 1000) // 타임존 서울, 이전 작업이 끝난 후 1초마다 실행 public void run1() { log.info("Scheduler 실행1 : {}", Thread.currentThread().getName()); } @Scheduled(zone = "Asia/Seoul", fixedDelay = 1000) // 타임존 서울, 이전 작업이 끝난 후 1초마다 실행 public void run2() { log.info("Scheduler 실행2 : {}", Thread.currentThread().getName()); }

앞서 설명한 것처럼 @Scheduled
어노테이션은 기본적으로 싱글 스레드
에서 실행됩니다. 하나의 스레드에서 여러개의 Task가 실행
될 경우 run1
이 종료되어야만 run2
가 실행되는 구조입니다.
만약 작업 중 Slow Query
또는 긴 시간을 소모하는 연산
과 같은 성능 저하 요인이 존재한다면
첫 번째 Task의 종료 시간 지연
→ 두 번째 Task의 시작 지연
→ 결과적으로 모든 스케줄링 작업에 지연 발생
이러한 문제를 해결하기 위해 Thread Pool
을 설정하여 여러 스레드에서 작업을 병렬로 실행할 수 있도록 구성할 수 있습니다.
Config 설정
@Configuration public class SchedulerConfig { @Bean public ThreadPoolTaskScheduler configureScheduler() { ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); threadPoolTaskScheduler.setPoolSize(5); // 스레드 풀 크기 threadPoolTaskScheduler.setThreadGroupName("tao scheduler thread pool"); // 스레드 그룹명 threadPoolTaskScheduler.setThreadNamePrefix("tao-scheduler-"); // 스레드명 접두사 threadPoolTaskScheduler.initialize(); // 스케줄러 초기화 return threadPoolTaskScheduler; } }

실행되는 Task가 각각 다른 스레드에서 실행되는 모습을 확인할 수 있습니다.
마무리
이번 포스팅에서는 Spring Boot의 @Scheduled
어노테이션을 사용하여 주기적인 작업을 자동화하는 방법에 대해 알아보았습니다. @Scheduled
를 활용하면 복잡한 스케줄링 작업을 손쉽게 관리할 수 있고, 다양한 옵션을 통해 세밀한 제어가 가능합니다.
'Spring' 카테고리의 다른 글
[SpringBoot] 트랜잭션 전파 속성 (Transaction propagation) (0) | 2025.02.02 |
---|---|
[SpringBoot] AWS S3 다중 이미지 파일 업로드 및 삭제 구현하기 (feat. MultipartFile) (2) | 2025.01.17 |
[SpringBoot] AWS SES로 이메일 전송 기능 구현하기 (0) | 2025.01.12 |
[SpringBoot] 다양한 동시성 제어 방법 (2) | 2024.12.20 |
[SpringBoot] Prometheus, Grafana를 이용한 모니터링 (0) | 2024.12.10 |
댓글을 사용할 수 없습니다.