들어가기 전

이번 포스팅에서는 Spring에서 제공해 주는 @Scheduled에 대해서 알아보겠습니다.

 

 

@Scheduled

@Scheduled는 스프링 프레임워크에서 제공해 주는 기능입니다.

특정 시간에 어떤 작업을 수행을 할 때 사용합니다.

Scheduled에는 아래와 같은 옵션들이 존재합니다.

  • cron : 작업 수행 할 시간설정
  • zone : 수행할 시간의 타임존 설정
  • fixedRate : 작업 시작 시간 기준으로 일정 간격마다 작업 설정
  • fixedDelay : 이전 작업 종료 시간 기준으로 일정 간격 후에 작업을 실행하도록 설정 

 

지금까지 @Scheduled의 속성에 대해 알아보았습니다. 
이제 스케줄러를 실행시키기 위한 설정과 각각의 속성에 대해서 예제를 통해서 알아보겠습니다.

 

 

스케줄러 사용을 위한 설정

 

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableScheduling
@SpringBootApplication
public class HoeStoryApplication {

    public static void main(String[] args) {
       SpringApplication.run(LockApplication.class, args);
    }
}

 

  • @EnableScheduling을 추가하면 스프링 프레임워크에서 지원하는 스케줄러 기능을 사용할 수 있습니다.


Zone

스케줄러를 실행할 지역을 설정합니다. 설정한 지역의 시간 기준으로 스케줄러를 수행합니다.

 

 

Cron

cron은 리눅스의 crontab과 유사합니다. 시간을 설정하는 방법은 아래와 같습니다.

 

* * * * * *

 

  • 첫 번째 : 0~59 (초)
  • 두 번째 : 0~59 (분)
  • 세 번째 : 0~23 (시)
  • 네 번째: 1~31(일)
  • 다섯 번째 : 1~12(월)
  • 여섯 번째 : 0~6(요일 - 0:일, 1:월, 2:화, 3:수, 4:목, 5:금, 6:토)
@Component
@Slf4j
public class HoeStorySchedule {

    @Scheduled(zone = "Asia/Seoul", cron = "*/30 * * * * *")
    public void cron() {
        log.info("cron을 이용한 스케줄러");
    }
}

 

 

 

위 코드는 zone 설정을 서울 기준으로 설정하였고 cron 설정을 통해 매일 30초씩 실행하는 스케줄러입니다.

결과는 아래와 같습니다.

 

 

 

 

fixedRate

이전 작업의 시작 시점부터 정의된 시간만큼 지난 후 작업을 실행합니다.

 

@Scheduled(fixedRate = 30000)
public void fixedRate() {
    log.info("fixedRate 스케줄러 실행");
}

 

  • fixedRate의 단위는 milliseconds입니다. 30000 -> 30초

fixedRate 속성으로 이루어진 스케줄러의 첫 작업이 22초에 시작하고 두 번째 작업이 52초 시작하여 30초 걸린 것을 확인할 수 있습니다.

즉 이전 작업의 시작 지점부터 정의된 시간(30초)만큼 지난 후 작업을 실행하는 것을 확인할 수 있습니다.

 

 

fixedDelay

fixedRate와 반대로 이전 작업의 종료 시점부터 정의된 시간만큼 지난 후 작업을 실행합니다.

 

@Scheduled(fixedDelay = 30000)
public void fixedDelay() throws InterruptedException {
    log.info("fixedDelay 스케줄러 시작");
    Thread.sleep(2000);
    log.info("fixedDelay 스케줄러 끝");
}

 

위 스케줄러를 실행시키면 결과는 아래와 같습니다.

 

  • 첫 번째 작업
    • 시작시간 : 9분 56초
    • 대기시간 : 2초
    • 끝난 시간 : 9분 58초
  • 두 번째 작업
    • 시작시간 : 10분 28초
    • 대기시간 : 2초
    • 끝난 시간 :  11분

첫 번째 작업이 종료된 시간과 두 번째 작업이 시작된 시간을 확인해 보면, 첫 번째 작업 종료 후 설정된 대기 시간(30초)이 지난 뒤에 두 번째 작업이 실행된 것을 확인할 수 있습니다.

 

FixedRate와 FixedDelay의 차이점

 

FixedRate는 두 번째 작업이 첫 번째 작업의 시작시간 기준으로 지정한 시간 뒤에 실행이 됩니다. 즉 규칙적으로 실행이 됩니다.

반면에 FixedDelay는 두 번째 작업이 첫 번째 작업이 끝나는 시간 기준으로 지정한 시간뒤에 실행이 됩니다.

만약 Slow Query와 같은 성능 저하를 일으키는 요소가 존재하면 끝나는 시간은 늦어지게 되고 두 번째 작업은 늦게 시작하게 됩니다.

FixedDelay는 FixedRate와 다르게 규칙적으로 실행되지 않습니다.

 

 

그림을 보면 FixedRate는 각 작업들이 규칙적인 시간(2초)에 시작하는 것을 확인할 수 있습니다. 물론 하나의 작업이 오래 걸려서 시작하는 시간의 규칙이 깨질 수 있습니다. 그럴 경우 FixedRate는 다른 작업이 끝나는 순간 바로 작업을 수행합니다.

반면에 FixedDelay는 FixedRate와 달리 작업 수행시간이 불규칙합니다. 이유는 다른 작업이 끝나고 난 뒤 지정한 시간이 지난 뒤에 작업을 수행하기 때문입니다.