Cron 표현식이란 무엇인가요?
Cron 표현식은 작업 스케줄러에게 태스크를 언제 실행할지 정확히 알려주는 간결한 스케줄링 문자열입니다. 이 형식은 1975년 Unix V7 cron 데몬에서 탄생했으며 그 이후 거의 변하지 않았습니다. 오늘날 Kubernetes CronJob, AWS EventBridge, GitHub Actions 워크플로우, Google Cloud Scheduler, GitLab CI, Jenkins 파이프라인, 모든 Linux 배포판에 포함된 crontab 바이너리에 동일한 5개 필드 문법이 사용됩니다. 이 문법은 13자 남짓한 문자열에 많은 의미를 담고 있기 때문에, 이를 평문 영어로 변환해주는 파서는 자신 있는 배포와 새벽 3시 롤백 사이의 차이를 만들어냅니다.
Cron 표현식은 어떻게 작동하나요?
표준 Cron 표현식은 반복 스케줄을 함께 정의하는 공백으로 구분된 5개의 필드를 갖습니다. 엔진은 매 분마다 현재 벽시계 시간과 표현식을 비교하고 5개 필드가 모두 일치할 때 작업을 실행합니다. 왼쪽에서 오른쪽 순서의 필드:
- 분 (0–59). 작업이 실행되는 시간 내의 분입니다.
0은 정시,30은 30분,*/5는 5분마다 (00, 05, 10, ...),15,45는 15분과 45분을 의미합니다. - 시 (0–23). 24시간 형식의 하루 중 몇 시인지입니다.
0은 자정,9는 오전 9시,17은 오후 5시입니다. 범위(9-17는 업무 시간)와 스텝 값(*/2는 2시간마다)은 분과 동일한 방식으로 작동합니다. - 날짜 (1–31). 실행할 달력의 날입니다.
1은 매월 1일,*는 매일,1,15는 1일과 15일을 의미합니다.31은 주의가 필요합니다 — 31일이 없는 달은 자동으로 건너뜁니다. - 월 (1–12 또는 JAN–DEC). 실행할 달입니다.
*는 매월,1,7은 1월과 7월,1-3은 1분기만을 의미합니다. 대부분의 구현에서 세 자리 월 이름은 대소문자를 구분하지 않습니다. - 요일 (0–7, 0과 7 모두 일요일을 의미). 특정 요일로 실행을 제한합니다.
1-5는 월요일부터 금요일,0,6은 주말,MON-FRI는 대부분의 파서에서 작동합니다. 날짜와 요일 모두 특정 값으로 설정되면 클래식 Cron은 어느 한쪽이 일치해도 실행됩니다 (논리적 OR). 이 동작은 항상 사람들을 놀라게 합니다.
Cron 표현식 파서를 사용하는 이유는 무엇인가요?
- 배포 전에 잘못된 해석을 미리 잡으세요. `0 2 */3 * *`는 3분마다가 아니라 매 3일 오전 2시에 실행됩니다 — 여기에 붙여 넣으면 배포 전에 영어로 확인할 수 있습니다.
- 대부분의 클라우드 스케줄러는 기본적으로 UTC로 실행됩니다. 현지 타임존에서 다음 10회 실행 시간을 미리 보면 DST 한 시간 오차가 새벽 3시에 알림을 보내기 전에 발견됩니다.
- `@daily`, `@weekly`, `@monthly` 같은 단축키는 편리하지만 모호합니다. 파서는 기본 5개 필드 형식을 보여주므로 정확히 무엇이 예약되었는지 알 수 있습니다.
- 필드별 빌더를 사용하면 한 열씩 스케줄을 구성하면서 사람이 읽을 수 있는 설명이 실시간으로 업데이트되는 것을 볼 수 있어, Cron 매뉴얼을 열 번째 다시 읽는 것보다 훨씬 빠릅니다.
Cron 표현식은 어디에 사용되나요?
Cron 구문은 작업이 시계에 따라 반복되어야 하는 모든 곳에 나타납니다. 각 플랫폼의 대표적인 주의사항과 함께 가장 흔한 세 가지 사용 사례:
- 백업 스케줄. 매일 밤 2시에 데이터베이스를 S3에 덤프하거나 매월 1일에 pg_dump 아카이브를 순환하는 전형적인 `crontab -e` 항목. `0 2 * * * /usr/local/bin/backup.sh` 같은 줄은 역사상 가장 많이 배포된 Cron 줄입니다. 분과 시를 정확히 맞추고, stderr를 내구성 있는 곳으로 리다이렉트하면 수동 체크리스트가 자동화 스크립트로 대체됩니다.
- GitHub Actions `schedule` 트리거. `.github/workflows/*.yml`의 `on.schedule.cron` 키는 표준 5개 필드 Cron을 허용하지만, 작업은 항상 UTC로 실행되며 러너 큐가 바쁘면 GitHub가 실행을 자동으로 건너뜁니다. 일반적인 패턴: 월요일부터 금요일까지 UTC 오전 9시에 요약을 보내는 `cron: '0 9 * * 1-5'`. BST에서 실제로 오전 10시에 도착하는 오전 9시 런던 요약을 약속하지 않도록 먼저 현지 타임존에서 미리 보세요.
- AWS EventBridge Scheduler. EventBridge Cron 표현식은 연도를 위한 6번째 필드를 가지며, 날짜 또는 요일 필드 중 하나에 `*` 대신 `?`를 요구합니다 — `cron(0 9 ? * MON-FRI *)`는 클래식 평일 오전 9시 Cron의 EventBridge 번역입니다. 예약된 Lambda 호출, ECS 태스크 실행, Step Function 상태 머신 시작에 사용됩니다. 클래식 Cron 구문과의 불일치는 CloudFormation 배포에서 `ValidationException` 오류의 가장 흔한 원인입니다.
실제 Cron 표현식은 어떻게 생겼나요?
0 9 * * 1-5를 살펴보세요 — 매 평일 오전 9:00에 실행됩니다. 필드를 왼쪽에서 오른쪽으로 읽으면: 0은 시간의 0분, 9는 24시간 기준 오전 9시, 날짜의 *는 매일, 월의 *는 매월, 요일의 1-5는 월요일부터 금요일로 제한합니다(표준 Cron 번호에서 1 = 월요일). 위 입력창에 붙여 넣으면 파서가 오전 09:00, 월요일부터 금요일까지로 확인하며, 선택한 IANA 시간대의 다음 10회 실행 날짜가 표시됩니다. AWS EventBridge 구문으로는 cron(0 9 ? * MON-FRI *) — 끝의 연도 필드와 표준 Cron의 * 대신 ?에 주목하세요. Quartz 표현식(선행 초가 있는 6개 필드)으로는 0 0 9 ? * MON-FRI. 세 가지 플랫폼, 세 가지 표면 형식, 하나의 스케줄.
Cron 표현식은 단 한 가지 방식으로 무자비합니다: 오타가 잘못된 시간에 실행되는 구문적으로 유효한 스케줄을 만들어내며, 코드 리뷰에서 잡을 오류가 없습니다. `0 0 1 * *`를 읽고 그것이 1월 1일이 아니라 매월 1일 자정에 실행된다는 것을 아는 것은 경험이 필요합니다. 위의 파서는 그 경험을 10초짜리 완전성 검사로 바꿔줍니다 — 표현식을 붙여 넣고, 영어를 읽고, 현지 시간대의 다음 10회 실행 시간을 확인하고, YAML이 커밋 메시지에 적힌 대로 실제로 작동한다는 것을 알고 배포하세요.
5개 필드와 6개 필드 Cron의 차이는 무엇인가요?
5개 필드 Cron은 분 단위 해상도를 가진 클래식 Unix 문법입니다. 6개 필드 Cron은 분 미만 스케줄링을 위한 선행 초 열을 추가합니다 — Quartz와 Spring의 @Scheduled에서 사용됩니다. AWS EventBridge도 6개 필드를 사용하지만, 추가 열은 초가 아닌 후행 연도입니다.
@hourly, @daily, @weekly는 무엇을 의미하나요?
1987년에 도입된 Vixie-cron 별칭입니다. @hourly = 0 * * * *, @daily = 0 0 * * *, @weekly = 0 0 * * 0, @monthly = 0 0 1 * *, @yearly = 0 0 1 1 *. @reboot는 부팅 시 한 번 실행됩니다. GitHub Actions와 EventBridge는 이 별칭을 지원하지 않습니다.
Cron에서 일요일은 0인가요, 7인가요?
클래식 Vixie Cron에서는 둘 다입니다 — 5-7과 같은 범위가 금요일부터 일요일로 자연스럽게 읽히도록 0과 7 모두 허용됩니다. 월요일은 항상 1, 토요일은 항상 6입니다. Quartz와 AWS EventBridge는 다른 관례를 사용합니다: 일요일이 1인 1-7. 가정하기 전에 플랫폼 문서를 확인하세요.
Cron은 일광 절약 시간(DST)을 어떻게 처리하나요?
엔진의 타임존에 따라 다릅니다. UTC(EventBridge, Kubernetes, GitHub Actions의 기본값)에서는 DST가 존재하지 않습니다. 현지 DST 시간대에서 클래식 Vixie Cron은 봄 시계 앞당기기 구간의 작업을 건너뛰고 가을 시계 되돌리기 중에는 두 번 실행합니다. systemd 타이머는 정확히 한 번 실행됩니다.