스프링 스케줄러는 Spring Framework의 일부로, 지정된 시간 간격이나 특정 시점에 자동으로 실행되어야 하는 작업을 스케줄링하는 데 사용된다.
스프링 스케줄러는 멀티쓰레딩과 비동기 실행을 지원하며 주로 백 그라운드에서 반복적으로 수행해야 하는 작업에 사용된다.
Spring의 버전별로 설정 방법이 상이하나 현재는 Spring, Springboot 모두 Application 클래스에 @EnableScheduling 으로 스케줄링 사용을 명시하는것이 일반적이다.
package com.corp.bookiki;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling // 스케줄링 사용을 명시한다.
public class BookikiApplication {
public static void main(String[] args) {
SpringApplication.run(BookikiApplication.class, args);
}
}
실제 작업할 Scheduler 클래스를 등록한다. @Component 어노테이션을 추가해 스프링 빈으로 주입한다. 그리고 @Sechduled 어노테이션을 활용하여 스케줄을 입력한 시간대에 맞게 실행하면 된다.
@Component는 스프링 빈에 등록된 클래스여야 한다.
@Scheduled규칙
- Method는 void 타입으로
- Method는 매개변수 사용 불가
package com.corp.bookiki.bookhistory.service;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import lombok.RequiredArgsConstructor;
@Component
@RequiredArgsConstructor
public class OverdueSchedular {
private final OverdueService overdueService;
@Scheduled(cron = "0 00 09 * * *")
public void checkOverdue() {
overdueService.processOverdueBooks();
}
}
// 매일 오전 9시에 OverdueService에 있는 processOverdueBooks()라는 로직이 실행된다.
스프링 스케줄러의 방식에는 두가지 방식이 있다.
스프링 스케줄르의 작업 간격은 fixedDelay 와 fixedRate 으로 설정할 수 있다. 둘 다 millliseconds 단위이다.
fixedDelay : 이전 Task의 종료 시점으로부터 정의된 시간만큼 지난 후 Task를 실행한다.package com.corp.bookiki.bookhistory.service;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import lombok.RequiredArgsConstructor;
@Component
@RequiredArgsConstructor
public class OverdueSchedular {
@Scheduled(fixedDelay = 1000) // 이전 Task가 종료되고 1초 뒤에 "Hello World!"를 출력한다.
public void run() {
System.out.println("Hello World");
}
}
fixedRate : 이전 Task의 시작 시점으로부터 정의된 시간만큼 지난 후 Task를 실행한다.@Scheduled(fixedRate = 5000) // 이전 Task가 시작한 5초 뒤에 "Hello World!"를 출력한다.
public void run() {
System.out.println("Hello World!");
}
fixedDelay vs fixedRate

fixedRate은 작업 수행시간과 관계없이 일정 주기마다 메소드를 호출하는 것이고
fixedDelay는 (작업 수행 시간을 포함하여) 작업을 마친 후부터 주기 타이머가 돌아 메소드를 호출하는 것이다.
** initialDelay : 스케줄러에서 메소드가 등록되자마자 수행하는 것이 아닌 초기 지연시간을 설정하는 것이다.
@Scheduled(fixedRate = 1000, initialDelay = 3000) // 3초의 대기시간(initialDelay) 후에 1초마다 "Hello World!"를 출력한다.
public void run() {
System.out.println("Hello World!");
}
cron 표현식을 사용하여 특정 시간 스케줄링을 설정할 수 있다.
@Scheduled(cron = "0 00 09 * * *") // 매일 오전 9시 "Hellow World!"를 출력한다.
public void run() {
System.out.println("Hello World!");
}
Cron 표현식 형식은 <초 (0~59)> <분 (0~59)> <시간 (0~23)> <일 (1~31)> <월 (1~12)> <요일 (0~6) (0: 일, 1: 월, 2:화, 3:수, 4:목, 5:금, 6:토)> <연도 (생략가능)> 이다.
* : 모든 조건(매시, 매일, 매주처럼 사용)을 의미
? : 설정 값 없음 (날짜와 요일에서만 사용 가능)
- : 범위를 지정할 때, : 여러 값을 지정할 때
/ : 증분값, 즉 초기값과 증가치 설정에 사용
L : 마지막 - 지정할 수 있는 범위의 마지막 값 설정 시 사용 (날짜와 요일에서만 사용 가능)
W : 가장 가까운 평일(weekday)을 설정할 때
# : N번째 주 특정 요일을 설정할 때 (-요일에서만 사용 가능)
cron 사용 예시
// 매일 오전 0시에 실행
@Scheduled(cron = "0 0 9 * * *")
public void run() {
System.out.println("Hello World!");
}
// 매달 10일, 20일 14시에 실행
@Scheduled(cron = "0 0 14 10,20 * ?")
public void run() {
System.out.println("Hello World!");
}
// 매달 마지막날 22시에 실행
@Scheduled(cron = "0 0 22 L * ?")
public void run() {
System.out.println("Hello World!");
}
// 1시간 마다 실행
@Scheduled(cron = "0 0 0/1 * * *")
public void run() {
System.out.println("Hello World!");
}
// 매일 9시00분 - 9시55분, 18시00분-18시55분 사이에 5분 간격으로 실행
@Scheduled(cron = "0 0/5 9,18 * * *")
public void run() {
System.out.println("Hello World!");
}
// 매달 1일 10시 30분에 실행
@Scheduled(cron = "0 30 10 1 * *")
public void run() {
System.out.println("Hello World!");
}
// 매년 3월 월-금 11시 30분에 실행
@Scheduled(cron = "0 30 11 ? 3 1-5")
public void run() {
System.out.println("Hello World!");
}
// 매달 마지막 토요일 1시 30분에 실행
@Scheduled(cron = "0 30 1 ? * 6L")
public void run() {
System.out.println("Hello World!");
}
멀티 쓰레드
비동기 처리
awaitility 라이브러리
참고
https://dev-coco.tistory.com/176
https://seriouskang.tistory.com/2
https://velog.io/@ktf1686/Spring-Spring-Scheduler-%EC%A0%81%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B8%B0