티스토리 뷰

Spring Boot

Spring Scheduler 사용하기

LuxuryCoding 2022. 8. 28. 22:01
728x90

일정한 시간간격 또는 일정한 시각에 특정 로직을 돌리기 위해서 사용하는 것을 Scheduler라고 합니다. 이런 Scheduler는 Spring에서 Spring Scheduler와 Spring Quartz라는 2가지 방식으로 제공됩니다. 

제가 했던 프로젝트에서는 Spring Scheduler 를 사용하여 1일 1주일 1달 별 랭킹을 구하는 예시로 사용했던 적이 있습니다.

 

Spring Scheduler

Spring Scheduler는 별도의 추가적인 의존성이 필요하지 않습니다. Spring Boot starter에 기본적인 의존성으로 제공됩니다. 사용하기 위해서는 @EnableScheduling 어노테이션을 붙여주면 됩니다.

 

package com.nice.study;

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

@EnableScheduling
@SpringBootApplication
public class NiceApplication {

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

}

@Scheduled 어노테이션 메서드에 붙여 주기만 하면 됩니다. 해당 어노테이션의 내부 값으로 scheduler가 실행 될 타이밍을 정할 수 있습니다. scheduling을 할 메서드는 2개의 조건을 가집니다.

  1. method는 void의 return 타입을 가진다. ❗
  2. method는 파라미터를 가질 수 없습니다.❗

@Scheduled(fixedDelay = 1000) // scheduler 끝나는 시간 기준으로 1초 간격으로 실행

@Component
public class SpringScheduler {

    @Scheduled(fixedDelay = 1000)
    public void test1()  throws InterruptedException{
        System.out.println("test1 : Park");
        Thread.sleep(5000); // 5초 지연
    }

    @Scheduled(fixedDelay = 1000)
    public void test2() {
        System.out.println("test2 : Jin");
    }

    @Scheduled(fixedDelay = 1000)
    public void test3() {
        System.out.println("test3 : Min");
    }
    
}

 

1초마다 스케쥴러가 실행되는 메소드를 만들었습니다. 

5초간 대기 시간이 있는 test1과 별개로 test2 test3 메소드는 1초마다 수행될 것 같지만  test1이 끝나야 test2, test3가 실행됩니다.

 

 

실행결과 화면을 보면 실제 스레드는 하나만 사용하고 있습니다.

Scheduler는 기본적으로 thread 1개를 이용하여 동기 형식으로 진행됩니다. 

즉 1번 스케줄이 끝나지 않으면 2번 스케줄이 시작시간이 되었다고 하더라도 시작되지 않습니다. 비동기 형식으로 진행하시고 싶으시다면 @EnableAsync 어노테이션을 이용할 수 있습니다

 

 

@Async  비동기로 구현  

Main에 @EnableAsync 붙이기

@EnableAsync
@EnableScheduling
@SpringBootApplication
public class NiceApplication {
  ...
}
@Component
public class SpringScheduler {

    @Async
    @Scheduled(fixedDelay = 1000)
    public void test1() throws InterruptedException {
        System.out.println("start Park : " + Thread.currentThread().getName());
        Thread.sleep(3000);
        System.out.println("end Park : " + Thread.currentThread().getName());

    }

    @Async
    @Scheduled(fixedDelay = 1000)
    public void test2() {
        System.out.println("start Jin : " + Thread.currentThread().getName());
        System.out.println("end Jin : " + Thread.currentThread().getName());
    }

    @Async
    @Scheduled(fixedDelay = 1000)
    public void test3() {
        System.out.println("start Min : " + Thread.currentThread().getName());
        System.out.println("end Min : " + Thread.currentThread().getName());
    }
}

다른 스레드 사용하는 실행결과

1초마다 스케쥴러가 실행되면서 각각의 스레드를 실행하는 것을 볼 수 있습니다.

 

동기 실행

그림 1

 

그림 2

즉 @Ascyn 어노테이션을 달지 않고  동기적으로 구현한다면  그림 1처럼 구현되고

비동기 방법을 사용한다면 작업 1이 수행되는 동안 작업2 작업 3도 수행됩니다.

 

Scheduler Cron 식 

 

cron = "* * * * * *"

* 초 *분 *시 *일 *월 *요일 *년도

<!-- 5분 마다 실행 ex) 00:05, 00:10. 00:15.... -->
@Scheduled(cron = "0 0/5 * * * *")

<!-- 1시간 마다 실행 ex) 01:00, 02:00, 03:00.... -->
@Scheduled(cron = "0 0 0/1 * * *")

<!-- 매일 오후 18시마다 실행 ex) 18:00 -->
@Scheduled(cron = "0 0 18 * * *")

<!-- 2018년도만 매일 오후 18시마다 실행 ex) 18:00 -->
@Scheduled(cron = "0 0 18 * * * 2018")

<!-- 매일 오후 18시00분-18시55분 사이에 5분 간격으로 실행 ex) 18:00, 18:05.....18:55 -->
@Scheduled(cron = "0 0/5 18 * * *")

<!-- 매일 오후 9시00분-9시55분, 18시00분-18시55분 사이에 5분 간격으로 실행  -->
@Scheduled(cron = "0 0/5 9,18 * * *")

<!-- 매일 오후 9시00분-18시55분 사이에 5분 간격으로 실행  -->
@Scheduled(cron = "0 0/5 9-18 * * *")

<!-- 매달 1일 00시에 실행 -->
@Scheduled(cron = "0 0 0 1 * *")

<!-- 매년 3월내 월-금요일 10시 30분에만 실행 -->
@Scheduled(cron = "0 30 10 ? 3 MON-FRI")

<!-- 매월 마지막날 저녁 10시에 실행 -->
@Scheduled(cron = "0 0 10 L * ?")

<!-- cron에 TimeZone 설정 추가 -->
@Scheduled(cron = "0 15 10 15 * ?", zone = "Asia/Seoul") // cron에 TimeZone 설정 추가

 

댓글
최근에 달린 댓글
최근에 올라온 글
Total
Today
Yesterday
«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31