티스토리 뷰

Spring

Springboot 예약된 작업 실행

따강아지 2023. 8. 25. 00:00

배치 또는 데몬을 통해서 예약된 시간에 프로그램을 실행 하는 것을 간단히 스프링을 사용해서 다음과 같은 방법으로 프로그램을 할 수 있습니다.

  • @Scheduled : 스프링 부트에서 @Scheduled 어노테이션을 이용하여 스케줄링
  • TaskScheduler : ThreadPoolTaskScheduler를 사용해서 여러개의 예약 작업을 실행  
  • Quartz : Quartz 라이브러리를 Spring-Boot에 통합 한 spring-boot-starter-quartz 를 사용

1. @Scheduled 사용 

1-1. @Scheduled사용한 개발

@Scheduled는 Spring에서 생성한 한개의 Thread에서 실행이 되므로 여러개 등록이 되었을 때 하나의 job이 끝나야 다 job이 실행 됩니다.

  • Application Class에 @EnableScheduling을 추가 하여  스케줄링 기능을 사용할 수 있는 상태로 만듭니다.
  • @Scheduled를 실행 할 서비스를 개발 합니다.
@EnableScheduling   // 스케줄링 기능활성화
@SpringBootApplication
public class HybirdApplication {  
	public static void main(String[] args) {
    	SpringApplication.run(HybirdApplication.class, args);
  	}
}

@Service
@Slf4j
public class AnnotationScheduledService {

  @Scheduled(initialDelay = 10000, fixedDelay = 10000 )
  public void scheduledJob() {
    log.debug("10 초 이후 job 다시 실행 "
            + Thread.currentThread().getName() + " : "
            + LocalDateTime.now().format(DateTimeFormatter.ofPattern("YYYY-MM-dd'T'HH:mm:ss")));
  }

  @Scheduled(cron = "0/15 * * * * *" )
  public void scheduledJobCron() {
    log.debug("cron 15초 이후 실행.. "
            + Thread.currentThread().getName() + " : "
            + LocalDateTime.now().format(DateTimeFormatter.ofPattern("YYYY-MM-dd'T'HH:mm:ss")));
  }
}


[hyomee] .... - cron 15초에 실행.. scheduling-1 : 2023-08-24T23:20:15
[hyomee] .... - 10 초 이후 job 다시 실행 scheduling-1 : 2023-08-24T23:20:18
[hyomee] .... - 10 초 이후 job 다시 실행 scheduling-1 : 2023-08-24T23:20:28
[hyomee] .... - cron 15초에 실행.. scheduling-1 : 2023-08-24T23:20:30

1-2. @Scheduled 속성

속성 설명 예제
cron  Cron 표현식을 사용하여 작업을 예약  : 6자
- 초 : 0 -59
- 분 : 0 - 59
- 시간 :  0 - 23,
- 일 : 1 - 31
- 월 : 1 - 12
- 요일 : 0: 일, 1: 월, 2:화, 3:수, 4:목, 5:금, 6:토

* : 모든 조건(매시, 매일, 매주처럼 사용)을 의미

? : 설정 값 없음 (날짜와 요일에서만 사용 가능)
- : 범위를 지정할 때
, : 여러 값을 지정할 때
/ : 증분값, 즉 초기값과 증가치 설정에 사용
L : 마지막 - 지정할 수 있는 범위의 마지막 값 설정 시 사용 (날짜와 요일에서만 사용 가능)
W : 가장 가까운 평일(weekday)을 설정할 때
# : N번째 주 특정 요일을 설정할 때 (-요일에서만 사용 가능)

* 매일 0시에 실행  :
- @Scheduled(cron = "0 0 0 * * *" )

* 10초 마다시에 실행  :
- @Scheduled(cron = "0/10 0 0 * * *" )

* 1시간 마다 실행  :
- @Scheduled(cron = "0 0 0/1 * * *" )

* 매일 오후 18시에 실행
@Scheduled(cron = "0 0 18 * * *") 

* 매달 5, 15일 01시 실행 
@Scheduled(cron = "0 0 1  5,15 * *")

* 매달 마지막 23시 실행 
@Scheduled(cron = "0 0 23  L ? ?")

* 매일 9시~19시 사이 5분 간격으로 실행
@Scheduled(cron = "0 0/5 9,18 * * *") 


 
zone  ron 표현식을 사용했을 때 사용할 time zone 설정, Default 는  Local time zone
fixedDelay milliseconds 단위로, 이전 Task의 종료 시점으로부터 정의된 시간만큼 지난 후 Task를 실행 ( 작업 수행 시간 포함됨 ) * 10 초 마다
@Scheduled(fixedDelay = 10000)
fixedDelayString fixedDelay동일 문자열  * 10 초 마다
@Scheduled(fixedDelayString = "10000")
fixedRate milliseconds 단위로, 이전 Task의 시작 시점으로부터 정의된 시간만큼 지난 후 Task를 실행 ( 작업 수행 시간과 관계 없음 ) * 10 초 마다
@Scheduled(fixedRate = 10000)
fixedRateString fixedRate 동일 문자열 * 10 초 마다
@Scheduled(fixedRateString = "10000")
initialDelay 초기 지연 시간 설정  * 3초 이후 5초 마다 실행 
@Scheduled(fixedRate = 5000, 
                      initialDelay = 3000)
initialDelayString initialDelay 동일 문자열  * 3초 이후 5초 마다 실행 
@Scheduled(fixedRate = 5000, 
                      initialDelayString = "3000")
timeUnit 스케줄 시간 단위 설정, default : MILLISECONDS TimeUnit.NANOSECONDS(1L),
TimeUnit.MICROSECONDS(1000L),
TimeUnit.MILLISECONDS(1000000L),
TimeUnit.SECONDS(1000000000L),
TimeUnit.MINUTES(60000000000L),
TimeUnit. HOURS(3600000000000L),
TimeUnit. DAYS(86400000000000L);

@Scheduled의 단점인 하나의 Thread에서 실행 하는 것을 Thread Pool을 만들어서 job을 실행 합니다

  • SchedulingConfigurer을 상속 받아 config를 구성 합니다.
@Configuration
public class SchedulerConfig implements SchedulingConfigurer {

  @Value("${scheduler.poolSize:10}")
  private int POOL_SIZE;

  /**
   * @Scheduled 에서 실행 되는 job을 각각의 Thread에 실행 하기 위한 SchedulerConfig
   * @param taskRegistrar the registrar to be configured.
   */
  @Override
  public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
    final ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
    threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
    threadPoolTaskScheduler.setThreadNamePrefix("hybird-scheduled-task-pool-");
    threadPoolTaskScheduler.initialize();

    taskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
  }

}


[hyomee] .... - 10 초 이후 job 다시 실행 hybird-scheduled-task-pool-1 : 2023-08-24T23:44:57
[hyomee] .... - cron 15초 이후 실행.. hybird-scheduled-task-pool-2 : 2023-08-24T23:45:00
[hyomee] .... - 10 초 이후 job 다시 실행 hybird-scheduled-task-pool-1 : 2023-08-24T23:45:07

 

그외 방법에 대해서는 다음을 참고 하세요

참고 : tutorials/spring-scheduling at master · eugenp/tutorials (github.com)

참고 : Scheduling in Jakarta EE | Baeldung

 

참고 : https://docs.spring.io/spring-boot/docs/2.0.x/reference/html/boot-features-quartz.html     

'Spring' 카테고리의 다른 글

Spring-Data Elasticsearch  (0) 2023.08.30
SpringBoot WebSocket  (0) 2023.08.26
Query-DSL 참고 문서  (0) 2023.08.24
Springboot - JPA 이름 규칙  (0) 2023.08.24
Springboot JPA Pagination  (0) 2023.08.23