Scheduler

이 문서에서는 스프링 3.0 이후에서 애노테이션 기반으로 스프링 스케줄러를 이용하는 방법에 대해서 살펴본다.

Spring Scheduler

스케줄러는 정해진 주기마다 작업을 실행하는 도구이다. 따라서 스케줄러를 생성하기 위해서는 반드시 주기작업을 설정해야 한다. 다음과 같은 작업들은 모두 스케줄러로 할 수 있는 작업에 해당한다.

  • 음원 차트를 매 정각마다 갱신한다.

  • 실시간 검색어를 10분마다 갱신한다.

  • 매일 아침 6시에 일일 포인트 사용내역을 초기화한다.

스케줄러를 이용할 때 주의할 점은 다음과 같다.

  • 주기가 짧을 수록 성능 저하의 가능성이 높아진다.

  • 스케줄러에서 수행하는 작업이 복잡할수록 성능 저하의 가능성이 높아진다.

  • 스케줄러를 많이 사용할수록 성능 저하의 가능성이 높아진다.

Spring dependency

스프링에서 스케줄러를 사용하려면 다음 의존성이 필요하다.

  • org.springframework.spring-task

Spring xml setting

스프링에서 스케줄러를 사용하려면 두 가지 방법을 고려할 수 있다.

  • 생성된 bean을 xml 설정에서 task 설정으로 등록하는 방법

  • xml 설정에 활성화 태그만 작성해둔 뒤 annotation으로 등록하는 방법

이 문서에서는 두 번째 방법을 사용한다.

namespace 설정

우선 xml 설정에서 task 관련 설정을 수행할 수 있도록 namespace를 추가해야 한다. 다음 이미지를 참고하여 root-context.xml 에 설정한다.

root-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
	
    <!-- task 관련 annotation 활성화 설정 -->
	<task:annotation-driven/>
		
</beans>

<task:annotation-driven/> 태그를 작성하여 task 관련 annotation을 활성화 처리한다. 이후 우리가 등록하는 task들을 자동으로 스캔하여 찾아준다.

Scheduler 등록

설정을 마쳤다면 스케줄러를 생성하고 등록해본다. 스케줄러는 Service 형태로 생성 및 등록할 것이며 다른 형태여도 무방하다.

ScheduleService.java

public interface ScheduleService {
	void work();
}

ScheduleServiceImpl.java

@Service
@Slf4j
public class ScheduleServiceImpl implements ScheduleService{
    @Override
    @Scheduled(fixedRate = 1000)
    public void work() {
        log.info("work 메소드 실행");
        log.info("현재시각 = {}", LocalDateTime.now());
    }
}

서버를 이용하여 현재 프로젝트를 실행해보면 1초 간격으로 현재시각이 출력되는 것을 확인할 수 있다. <task:annotation-driven/> 설정을 해두었기 때문에 @Scheduled 애노테이션을 찾아서 자동으로 시작 시 옵션에 맞게 구동되도록 해주는 것이다.

@Scheduled 옵션

@Scheduled에는 다음과 같은 옵션을 사용할 수 있다. API

  • cron : unix 계열에서 사용하는 cron과 같은 표현식 형태로 주기를 설정

  • fixedDelay : 작업 종료와 재시작 사이의 간격을 밀리초(ms) 단위로 설정

  • fixedDelayString : 작업 종료와 재시작 사이의 간격을 java.time.Duration 규격에 맞게 설정

  • fixedRate : 작업 시작과 시작 사이의 간격을 밀리초(ms) 단위로 설정

  • fixedRateString : 작업 시작과 시작 사이의 간격을 java.time.Duration 규격에 맞게 설정

  • initialDelay : 작업의 최초 시작 전의 대기 간격을 밀리초(ms) 단위로 설정

  • initialDelayString : 작업의 최초 시작 전의 대기 간격을 java.time.Duration 규격에 맞게 설정

  • zone : cron 표현식을 적용시킬 타임 지역을 설정

cron 표현식

cron 표현식의 사용 형태에 대해 살펴본다.

cron 표현식 형식

@Schedule("초설정  분설정  시간설정  날짜설정  월설정  요일설정")

또는

@Schedule("초설정  분설정  시간설정  날짜설정  월설정  요일설정  연도설정")

일반적으로 연도를 설정할 일은 거의 없다.

주요 기호 설명

cron 표현식에서 사용하는 주요 기호들은 다음과 같다.

  • *

    • 전체(All)을 의미

  • ?

    • 아무때나(Any)를 의미

    • 일, 요일 자리에만 사용 가능

    • 일이나 요일에 패턴이 지정될 경우 반대쪽은 ? 로 설정한

  • ,

    • 값을 여러 개 지정할 때 사용

    • 11, 15, 20으로 설정하면 3개가 설정

  • -

    • 범위 지정 기호

    • 10-20 은 10부터 20까지 범위를 설정

  • /

    • 주기 설정

    • */3 은 해당 항목을 3번마다 실행하도록 설정

  • L

    • 마지막 날

  • W

    • 가장 가까운 영업일(월-금)

  • #

    • 주차 지정

    • 3#2는 2주차 3(수요일)을 의미

cron 표현식 예시

@Schedule(cron="") 안에 사용할 수 있는 표현식과 그에 대한 해석은 다음과 같다.

  • * * * * * *

    • *초 *분 *시 *일 *월 *요일

    • 매 초 간격으로 실행

  • */1 * * * * *

    • 1초마다 *분 *시 *일 *월 *요일

    • 매 1초 간격으로 실행

  • */2 * * * * *

    • 2초마다 *분 *시 *일 *월 *요일

    • 매 2초 간격으로 실행

  • 10,20 * * * * *

    • 10,20초 *분 *시 *일 *월 *요일

    • 매분 10초와 20초에 한 번씩 실행

  • 10-20 * * * * *

    • 10~20초 *분 *시 *일 *월 *요일

    • 매분 10초부터 20초 사이에 1초 간격으로 실행

  • 0 * * * * *

    • 0초 *분 *시 *일 *월 *요일

    • 매분 0초에 실행(1분마다)

  • 0 */1 * * * *

    • 0초 1분마다 *시 *일 *월 *요일

    • 1분마다 0초에 실행

  • 0 */5 * * * *

    • 0초 5분마다 *시 *일 *월 *요일

    • 5분마다 0초에 실행

  • 0 0 * * * *

    • 0초 0분 *시 *일 *월 *요일

    • 매 시 정각에 실행

  • 0 0 */2 * * *

    • 0초 0분 2시간마다 *일 *월 *요일

    • 매 2시간마다 정각에 실행

  • 0 0 6 * * *

    • 0초 0분 6시 *일 *월 *요일

    • 매일 아침 6시 정각에 실행

  • 0 0 6 * * W

    • 0초 0분 6시 *일 *월 수요일

    • 매주 수요일 아침 6시 정각에 실행

  • 0 0 6 L * ?

    • 0초 0분 6시 마지막날 *월 요일무관

    • 매월 마지막날 아침 6시 정각에 실행

  • 0 0 6 ? * 4L

    • 0초 0분 6시 아무날 매월 마지막수요일

    • 매월 마지막 수요일 아침 6시 정각에 실행

  • 0 0 6 ? * 4#3

    • 0초 0분 6시 아무날 매월 3번째수요일

    • 매월 3주차 수요일 아침 6시 정각에 실행

Last updated