Spring 크론 표현식 생성기

Spring @Scheduled 크론 표현식을 넣으면 언제 실행되는지 한국어로 풀어 주고, 고른 시간대 기준으로 다음 실행 시각 10번을 보여 줍니다. Spring Framework CronExpression 규칙(초부터 시작하는 6자리, L·W·#)을 따르며, 5자리 유닉스 크론과 7자리 Quartz 크론을 붙여 넣으면 Spring 형식으로 바꿔 줍니다.

브라우저에서만 동작 · 업데이트 · 작성 Srue, 백엔드 개발자 · View in English

초 · 분 · 시 · 일 · 월 · 요일

뜻

매주 월~금요일 09:00

자리별 해석
자리값해당 값
초00
분00
시99
일*모두
월*모두
요일MON-FRI1, 2, 3, 4, 5

다음 실행 10번

올바른 표현식을 넣으면 실행 일정이 나옵니다.

Spring 에서 쓰기

@Scheduled(cron = "0 0 9 * * MON-FRI", zone = "UTC")

application.yml 로 빼기

app:
  jobs:
    report:
      cron: "0 0 9 * * MON-FRI"

# @Scheduled(cron = "${app.jobs.report.cron}", zone = "UTC")

Spring 크론 vs 유닉스 크론 vs Quartz

스케줄이 엉뚱하게 도는 경우는 대부분 다른 종류의 크론식을 그대로 가져와서입니다. 세 가지는 비슷해 보여도 자리 수, 요일 번호, 일·요일을 합치는 방식이 다릅니다.

Spring·유닉스·Quartz 크론 차이
Spring (@Scheduled)유닉스 crontabQuartz
자리 수6 — 초부터5 — 초 없음6 또는 7 (연도)
일요일0 또는 70 또는 71
월요일112
일 + 요일 지정둘 다 맞아야 실행하나만 맞아도 실행한쪽은 ?
L, W, #지원미지원지원

자주 쓰는 Spring 크론 예시

Spring 크론 예시와 뜻
표현식뜻
*/30 * * * * *30초마다
0 */5 * * * *5분마다
0 0 * * * *매시 정각
0 0 9 * * *매일 09:00
0 0 9 * * MON-FRI매주 월~금요일 09:00
0 0/30 9-18 * * MON-FRI매주 월~금요일 9~18시 사이 30분마다
0 0 0 1 * *매월 1일 00:00
0 0 23 L * *매월 마지막 날 23:00
0 0 10 * * MON#1매월 첫째 월요일 10:00
0 0 18 * * FRIL매월 마지막 금요일 18:00
0 0 9 15W * *매월 15일에 가장 가까운 평일 09:00

L은 그달의 마지막 날, L-2는 말일 이틀 전, 15W는 15일에 가장 가까운 평일(달을 넘어가지 않음)입니다. 요일 자리의 FRIL은 마지막 금요일, MON#2는 둘째 월요일입니다.

운영에서 자주 겪는 문제

  • 스레드가 하나뿐입니다. Spring Boot 스케줄러 풀은 기본 1개(spring.task.scheduling.pool.size=1)라서 작업 하나가 오래 걸리면 다른 스케줄도 밀립니다.
  • 인스턴스마다 다 실행됩니다. 서버가 3대면 하루 한 번 보내는 메일이 3통 나갑니다. ShedLock 같은 잠금을 쓰거나 한 대에서만 돌리세요.
  • 시간대가 어긋납니다. 컨테이너는 대개 UTC 입니다. zone을 명시하세요.
  • 등록된 작업 확인. Spring Boot Actuator 의 /actuator/scheduledtasks에서 실제로 등록된 크론식을 볼 수 있습니다. 설정값이 의도대로 들어갔는지 확인할 때 유용합니다.

자주 묻는 질문

“Cron expression must consist of 6 fields” 오류는 왜 나나요?

"0 9 * * *" 같은 5자리 유닉스 크론을 넣었기 때문입니다. Spring 크론은 맨 앞에 초 자리가 있어서 "0 0 9 * * *"처럼 6자리여야 합니다. 위 도구에 5자리를 그대로 붙여 넣으면 Spring 형식으로 바꿔 줍니다.

일요일은 0인가요, 7인가요?

Spring 은 0과 7 모두 일요일로 보고, 1이 월요일입니다. SUN~SAT 이름도 쓸 수 있습니다. Quartz 는 1이 일요일이라, Quartz 에서 옮겨 올 때 요일 숫자가 하루씩 밀리는 실수가 가장 흔합니다.

일과 요일을 둘 다 지정하면 어떻게 되나요?

Spring 은 둘 다 맞는 날에만 실행합니다. "0 0 9 13 * FRI"는 13일의 금요일에만 돕니다. 유닉스 크론은 둘 중 하나만 맞아도 실행하므로, crontab 에서 가져온 식은 동작이 달라집니다.

@Scheduled 는 어느 시간대 기준으로 도나요?

zone 속성을 주지 않으면 JVM 기본 시간대입니다. 컨테이너는 보통 UTC 라서 09:00으로 쓴 작업이 한국 시간 18:00에 도는 일이 생깁니다. @Scheduled(cron = "0 0 9 * * *", zone = "Asia/Seoul")처럼 시간대를 명시하세요.

설정으로 스케줄 작업을 끄려면?

크론 값을 "-"(Scheduled.CRON_DISABLED)로 두면 됩니다. @Scheduled(cron = "${app.jobs.report.cron}")처럼 설정에서 읽게 해 두면, 특정 환경에서만 app.jobs.report.cron: "-"로 끌 수 있습니다.