크론 잡
Cron Job
개념
매일 새벽 3시처럼 미리 적어 둔 시각이 되면 사람 손 없이 저절로 실행되는 작업을 말합니다.
등장 배경
서버가 해야 할 일 중에는 누가 요청해서 생기는 일이 아닌 것이 있습니다. 어제 하루치 사용량을 집계하는 일, 한 달이 지난 임시 파일을 지우는 일, 매달 1일에 청구서를 만드는 일이 그렇습니다. 화면에서 버튼을 누르는 사람이 없으니 이런 일은 누군가 때가 되면 기억해 내서 직접 돌려야 했습니다.
그 시절 운영 담당자의 하루는 알람으로 시작했습니다. 사용량이 가장 적은 새벽에 집계를 돌려야 하니 3시에 일어나 서버에 접속해 명령어를 한 줄 치고, 결과가 잘 나왔는지 확인한 뒤 다시 잤습니다. 이 방식은 사람이 늘 그 자리에 있어야만 굴러갔습니다. 담당자가 휴가를 가면 그 주의 집계가 통째로 비었고, 인수인계를 받은 사람이 명령어를 잘못 치면 아무도 모른 채 하루치 숫자가 어긋났습니다.
문제는 게으름이 아니라 구조였습니다. 매일 같은 시각에 같은 명령을 실행한다는 약속을 사람의 기억에 맡겨 둔 것이 원인이었습니다. 크론 잡은 그 약속을 서버에게 넘깁니다. 요청을 받아 응답을 돌려주는 서버는 사람이 보지 않을 때도 켜져 있으니, 시계를 보고 때가 되면 대신 명령을 실행해 줄 수 있습니다. 시각과 명령을 한 줄로 적어 두는 것이 사람이 할 일의 전부가 됩니다.
작동 방식
시각을 적은 줄과 실행할 명령을 짝지어 등록해 두면, 서버에 상주하는 스케줄러가 1분마다 시계를 확인하다가 조건에 맞는 순간 그 명령을 실행합니다.
시각은 빈칸 다섯 개로 적습니다. 순서가 정해져 있습니다.
- 분 — 0 부터 59 까지입니다.
- 시 — 0 부터 23 까지입니다.
- 일 — 그달의 며칠인지입니다.
- 월 — 1 부터 12 까지입니다.
- 요일 — 0 이 일요일입니다.
각 자리에는 숫자를 그대로 쓰거나, 아무 때나 해당한다는 뜻의 별표를 씁니다. 그래서 0 3 * * * 는 날짜와 요일을 가리지 않고 매일 3시 0분에 실행하라는 뜻이 되고, */10 * * * * 는 10분마다, 0 9 1 * * 는 매달 1일 아침 9시에 한 번을 뜻합니다. 처음 보면 암호 같지만 다섯 칸의 순서만 외우면 읽힙니다.
등록한 뒤 걸리는 지점은 대개 셋입니다.
- 시간대입니다. 서버 시계가 세계 표준시로 맞춰져 있으면
0 3 * * *은 한국 시각 낮 12시에 돕니다. 새벽에 돌 줄 알았던 무거운 집계가 사용자가 가장 많은 시간에 도는 사고가 여기서 납니다. - 겹침입니다. 10분마다 도는 작업이 12분 걸리기 시작하면 앞선 실행이 끝나기 전에 다음 실행이 시작됩니다. 같은 데이터를 둘이 동시에 건드려 값이 두 번 더해지는 일이 이때 생깁니다. 실행 중이면 건너뛰도록 잠금을 걸어 막습니다.
- 실패 처리입니다. 스케줄러는 명령을 실행할 뿐 결과를 보지 않습니다. 작업이 중간에 죽어도 다음 시각에 아무 일 없었다는 듯 새로 시작하고, 실패한 회차는 영영 빈 채로 남습니다. 그래서 실행 결과를 기록하고 실패하면 알림을 보내는 장치를 따로 붙입니다.
쓰이는 곳
정해진 시각에 한 번 돌면 되는 일, 그리고 사용자를 기다리게 하지 않아도 되는 일이 여기로 갑니다.
- 집계와 정산 — 어제 하루 동안 쌓인 기록을 모아 오늘 볼 숫자로 만듭니다. 매달 1일에 지난달 사용량을 계산해 청구서를 만드는 일도 같은 자리입니다.
- 정리 — 30일이 지난 임시 파일을 지우고, 만료된 초대 링크를 무효로 바꿉니다. 쌓이는 속도가 느려서 매일 한 번이면 충분한 일들입니다.
- 동기화 — 외부 서비스의 데이터를 가져와 우리 쪽과 맞춥니다. 환율이나 요금제 정보처럼 실시간일 필요가 없는 값이 여기 해당합니다.
- 예정된 발송 — 체험판 종료 사흘 전 안내 메일처럼 날짜 조건이 맞는 사람을 골라 한 번에 보냅니다.
페이지덱에서는 매일 새벽 4시에 도는 작업이 팀별 문서 사용량을 집계해 관리자 화면의 숫자를 갱신합니다. 사용자가 그 화면을 열 때마다 계산하면 몇 초씩 걸릴 일을, 하루 한 번 미리 계산해 두고 읽기만 하게 만든 것입니다.
반대로 사용자가 버튼을 누른 결과로 생기는 일은 여기 오지 않습니다. 문서를 PDF 로 내보내는 요청은 누른 즉시 처리를 시작해야 하므로 백그라운드 작업으로 넘기고, 그런 요청이 한꺼번에 몰릴 때 순서대로 줄 세우는 일은 메시지 큐가 맡습니다.
실무 용례
"그 집계 크론으로 매일 새벽 4시에 돌고 있어요."
사람이 손으로 돌리는 일이 아니라 정해진 시각에 자동으로 실행된다는 뜻입니다.
"어젯밤 크론이 실패했는데 알림이 안 와서 오늘 아침에야 알았습니다."
실행 결과를 감시하는 장치가 없어 하루치 결과가 빈 채로 지나갔다는 말입니다.
"이건 크론 말고 이벤트로 받는 게 맞을 것 같아요."
시각에 맞춰 도는 대신 어떤 일이 일어나는 순간 처리하자는 제안입니다.
페이지덱에서 이 이야기가 나오는 자리는 대개 숫자가 안 맞을 때입니다. 지현이 관리자 화면의 사용량이 어제와 같다고 말하면, 태오가 새벽에 돈 작업의 기록을 열어 보고 중간에 멈췄는지 확인합니다. 멈췄다면 손으로 한 번 더 돌려 그날 치를 채우고, 왜 멈췄는지는 따로 봅니다.
흔한 오해
적어 둔 시각에 반드시 실행된다고 믿는 경우가 많습니다. 시계를 보고 도는 장치이니 자연스러운 기대입니다. 실제로는 그 시각에 서버가 살아 있어야 실행되고, 배포 중이거나 장비가 재시작되는 동안에 그 순간이 지나가면 그 회차는 그냥 없었던 일이 됩니다. 매달 1일 정산처럼 한 번 빠지면 곤란한 작업은 실행 여부를 따로 기록해 두고, 빠진 회차를 나중에 채워 넣을 수 있게 만들어 둡니다.
한 번 걸어 두면 손이 안 간다는 생각도 흔합니다. 등록은 한 줄이지만 그 뒤로 데이터는 계속 늘어납니다. 처음에 3분 걸리던 집계가 6개월 뒤 25분이 되고, 10분 간격으로 걸어 둔 작업이라면 이때부터 매번 겹쳐 돕니다. 걸어 둔 시각 옆에 실행 시간이 얼마나 걸렸는지를 함께 남겨 두면 이 변화를 미리 봅니다. 3분이 5분이 되고 12분이 되는 흐름이 보이면 간격을 늘리거나 처리할 범위를 쪼갤 시점을 고장이 나기 전에 정할 수 있습니다.
자주 헷갈리는 용어
같이 보면 좋은 페이지
마지막 업데이트 2026-09-16