Quartz CronTrigger로 알아보는 Cron 표현식

최근에 회사에서 Quartz를 사용할 일이 생겨 Cron 표현식을 정리해 보았습니다. 자주 쓰는편이 아니라 필요할땐 대충 구글링 해서 베껴쓰곤 했었는데, 비록 몇페이 안되지만 정리하고 나니 뿌듯하네요. 표현식은 unix 시스템과도 사용법이 동일하니 관리자 분들도 이해하고 있으면 유용할 것 같습니다.

crontab

Quartz에서 SimpleTrigger와 CronTrigger

만약에, 작업(Job) 실행이 달력 개념을 기반으로 반복된다면 정확한 간격(Interval)을 사용하는 SimpleTrigger보다 CronTrigger가 더 유용하게 사용될 수 있습니다.
CronTrigger는 “매일 금요일 정오”, 또는 “매 주말 오전 9시”, “1월 한달간 매주 월요일, 수요일, 금요일 오전 9시에서 10시 사이 5분 간격”과 같이 스케줄을 설정할 수 있습니다.
물론, SimpleTrigger처럼 CronTrigger도 스케줄이 적용될 시작 시간과 만료 시간을 설정할수 있습니다.

Cron 표현식(Expression)

Cron표현식은 CronTrigger 인스턴스를 설정하는데 사용됩니다. Cron표현식은 7개의 단위 표현식으로 구성된 문자열 입니다. 각 단위는 스케줄을 세분화 하여 상세하게 기술합니다. 이 단위 표현식은 공백으로 구분됩니다.

  1. 초(Seconds)
  2. 분(Minutes)
  3. 시(Hours)
  4. 일(Day-of-Month)
  5. 월(Months)
  6. 요일(Days-of-Week)
  7. 연도(Year) - optional

이들을 조합한 Cron표현식은 “0 0 12 ? * WEB”와 같이 표현됩니다. 이것은 “매주 수요일 정오”를 의미 합니다. (연도는 생략)

각 단위 표현식은 범위나 목록을 가질 수 있습니다. 예를들어, 앞의 예제에서 수요일(WED)은 “MON-FRI”, “MON,WED,FRI” 또는 “MON-WED,SAT”와 같이 대채될 수 있습니다.

와일드카드 문자는 이 필드에서 가능한 “매번”을 표현합니다. 그러므로, 앞의 예제에서 “월(Month)”필드의 ‘’표시는 단순히 “매월”을 의미합니다. 요일(Day-of-Week)필드에 ‘’는 “한주동안 매일”을 의미합니다.

모든 필드는 검증할 수 있는 값의 집합으로 구성됩니다. 값은 명확하게 표현해야 합니다. 분과 초는 0에서 59사이의 숫자여야 하고, 시간은 0에서 23사이의 숫자여야 합니다. 일(Day-of-Month) 필드는 1-31사이의 어떤 숫자나 사용할 수 있습니다.

월(Months)는 숫자 0에서 11, 또는 물자열 JAN, FEB, MAR, APR, MAY, JUN. JUL, AUG, SEP, OCT, NOV, 그리고 DEC를 사용할 수 있습니다. 요일(Days-of-Week)은 1과 7(1=일요일)사이의 숫자를 사용하거나, 문자열 SUN, MON, TUE, WED, THU, FRI, 그리고, SAT를 사용할 수 있습니다.

“/” 문자는 값의 증가 표현에 사용될 수 있습니다. 예를들어, 분(Minutes) 필드에 ‘0/15’ 를 사용한다면, 이것은 “0분 부터 시작하여 (시간의) 매 15분 마다”를 의미합니다. 만약, 분(Minutes) 필드에 ‘3/20’을 사용한다면, “3분부터 시작하여 매 20분 마다”를 의미하므로, ‘3,23,43’을 분 필드에 나열한것과 같습니다. 미묘하게 주목할 점은 “/35”의 경우 “매 35분 마다”를 의미하지 않는다는 것입니다. 이것은, “0분부터 시작하여 매 35분 마다”이므로, 달리 표현하면 ‘0,35’를 나열한 것과 같습니다.

“?”문자는 일(day-of-month)와 요일(day-of-week) 필드에서만 허용됩니다. 이것은 “설정 값 없음”에 사용됩니다. “?”문자는 두 필드(일, 요일)중 하나만 설정할 경우에 나머지 필드에 유용하게 사용됩니다. 다음 섹션의 예제를 보면 이해가 쉬울 것입니다.

“L”문자는 일(day-of-month)과 요일(day-of-week) 필드에서만 허용됩니다. 이 문자는 “마지막(last)”의 첫글자에서 따왔습니다. 하지만, 두 필드에서 조금 다른 의미로 해석됩니다. 예를들어, “L”이 일(day-of-month) 필드에서 사용되었을 경우 “이달의 마지막 날”을 의미합니다. 1월이면 31일이 되고, 2월은 (윤년이 아닌경우)28일이 됩니다. 요일(day-of-week) 필드에서 사용될 경우에는 단순히 “7” 또는 “SAT”를 의미합니다. 하지만, “L”이 특정값의 뒤에 올경우, 이것은 “이달의 마지막 x요일”이 됩니다. 예를들어, “6L” 또는 “FRIL”은 “이달의 마지막 금요일”을 의미합니다. 또한, 마지막 날에서 특정 기간(offset)을 설정할 수도 있습니다. “L-3”과 같이 설정하면 “(이달의 마지막일로부터)3일전부터 마지막날 까지”의 기간을 의미합니다. “L”옵션을 사용할때, 값의 목록이나 범위를 명확히 하지 않을 경우 예상밖의 결과를 낳을 수 있으므로 주의가 필요합니다.

“W”는 주어진 날로부터 가장 가까운 평일(월요일~금요일)을 가르킵니다. 만일, “15W”라는 값을 일(day-of-month)필드에 설정하면, “이달의 15번째날에서 가장 가까운 평일”을 의미합니다.
“#”은 “이달의 n번째 X요일”을 가르킵니다. 예를들어, “6#3” 또는 “FRI#3”을 요일(day-of-week) 필드에 설정할 경우 이것은 “이달의 세번째 금요일”을 의미 합니다.

이제 몇가지 표현식 예제를 통해 확실히 의미를 파악하도록 하겠습니다.

Cron 표현식 예제

*매 5분 마다 실행

“0 0/5 * ?”

*10초뒤 5분마다 실행. (10:00:10 am, 10:05:10 am, …)

“10 0/5 * ?”

*매주 수요일과 금요일 10:30, 11:30, 12:30, 13:30 에 실행

“0 30 10-13 ? * WED,FRI”

*매월 5일, 20일 오전 8시부터 오전 10시 사이에 30분 간격으로 실행. 이 트리거는 10:00 am에는 실행이 되지 않고, 8:00, 8:30, 9:00, 9:30 에만 실행 된다.

“0 0/30 8-9 5,20 * ?”

어떤 스케줄링 작업은 너무 복잡한 트리거 표현식을 요구하기도 합니다. 이럴 경우에는 단순히 두개의 트리거로 나누어 작업을 등록하길 권장 합니다.

참고 페이지 : Quartz Framework. Lesson 6: Cron Trigger