스케줄링(Scheduling)은 특정 작업이나 프로세스를 정해진 시간에 실행하거나 일정한 주기로 반복해서 실행하는 것을 의미한다.컴퓨터 시스템에서 스케줄링은 CPU와 같은 자원을 효율적으로 관리하고, 애플리케이션에서는 주기적인 작업을 자동으로 처리하는 데 사용된다. 물론 자바에서는 스프링 진영에서는 @Scheduled 애노테이션을 통해 스케줄링을 쉽게 구현할 수 있다.
@Scheduling 설정
@Scheduling 을 사용해주기 위해서는 Bean Scan 범위 안에서 @EnableScheduling 를 설정해주어야 한다.
@Scheduling 속성
fixedRate
@Scheduling 메서드를 고정된 기간 동안 반복해서 실행한다. 기본 시간 단위는 밀리초이지만, timeUnit 속성으로 다른 시간 단위를 설정할 수 있다. 정확한 프록세스는 아래와 같다.
Started ~~Application in 2.588 seconds (process running for 4.066)
작업 실행
3초 대기
작업 실행
…반복…
fixedDelay
@Scheduling 메서드의 마지막 호출이 끝난 시점과 다음에 호출될 시점 사이에 지정한 시간만큼 간격을 두어 작업을 반복한다. 마찬가지로 기본 시간 단위는 밀리초이지만 timeUnit 속성으로 다른 시간 단위를 설정할 수 있다.
앞서 살펴본 fixedRate 와 역할은 동일하지만, fixedDelay 방식은 SimpleAsyncTaskScheduler 와 함께 단일 스케줄러 스레드에서 동작하는것에서 차이점이 있다. 정확한 프록세스는 아래와 같다.
Started ~~Application in 2.593 seconds (process running for 3.99)
작업 실행 (마지막 호출)
3초 대기
작업 실행 (다음 호출)
…반복…
initialDelay
@Scheduling 메서드의 첫 작업을 실행하기까지 지연시간을 의미한다. 마찬가지로 기본 시간 단위는 밀리초이지만 timeUnit 속성으로 다른 시간 단위를 설정할 수 있다. 정확한 프로세스는 아래와 같다.
Started ~~Application in 2.593 seconds (process running for 3.99)
10 초 (initialDelay) 만큼 대기
작업 실행 (마지막 호출)
3초 대기 (fixedRate)
작업 실행 (다음 호출)
…반복…
cron
작업 반복을 위한 Cron Expression 을 적어주면 된다. 리눅스 crontab 에서 사용되는 Cron Expression 은 5개의 필드로 이루어져 있지만, @Scheduled 에서 사용되는 Cron Expression 은 6개의 필드로 이루어져 있다.
리눅스 Crontab
@Scheduled cron
코드는 매우 간단하다. 작업을 수행할 주기를 Cron Expression 에 맞게 작성해주면 된다. 아래 코드는 5초마다 로그를 찍는 작업을 나타낸 것이다.
추가적으로 @Scheduled 의 속성들 중 String 값을 갖는 속성들은 스프링 SpEL(SPring Expression Language) 을 사용하여 cron 과 같은 설정을 외부로 분리하여 유연하게 관리할 수 있다. 아래 예시는 application.yml 혹은 properties 로부터 schedule.cron.expression 설정을 가져와 cron 값으로 사용할건데, 만약 설정이 되어있지 않다면 Default 로 */3 * * * * * 값을 사용할 것이라는 의미이다.
Cron 에 대한 더 자세한 내용은 @Scheduled 어노테이션 Docs 를 보면 된다.
scheduler
@Scheduled 메서드가 사용할 스케줄러를 지정할 수 있다. scheduler 의 이름은 TaskScheduler 타입의 Bean 이름을 적어주면 된다.
TaskScheduler Bean 이 없거나, SchedulingConfigurer 로 직접 스케줄러를 설정해주지 않으면, Main Thread 는 별도의 Thread 를 만들어 Single Thread 환경에서 모든 스케줄링을 관리하게 된다. 아래 사진의 scheduling-1 가 Main Thread 가 스케줄링을 위해 만든 별도의 Thread 이다. 관련 내용은 다음 포스팅에서 언급할 예정이다.