프로그래밍/운영체제

systemd OnCalendar 사용법

포도알77 2026. 8. 10. 15:54

systemd timer에서 특정 시각이나 반복 일정을 잡을 때 핵심은 OnCalendar=입니다. cron처럼 벽시계 기준으로 실행할 수 있지만, 실제 동작은 timer unit, service unit, 정확도 보정, 지연 옵션까지 함께 봐야 안전합니다.

결론부터 말하면 정해진 날짜와 시각에 맞춰 작업을 실행해야 한다면 OnCalendar=를 쓰고, 부팅 후 몇 분 뒤나 마지막 실행 후 일정 시간이 지난 뒤처럼 상대 시간이 중요하면 OnBootSec=, OnUnitActiveSec= 같은 monotonic timer를 봅니다. 운영 환경에서는 systemd-analyze calendar로 표현식을 먼저 검증한 뒤 timer를 활성화하는 편이 좋습니다.

OnCalendar는 무엇을 지정할까

OnCalendar=는 systemd timer unit의 [Timer] 섹션에서 쓰는 calendar event 표현식입니다. 공식 systemd.timer 문서 기준으로, 이 값은 realtime, 즉 벽시계 기준 timer를 정의합니다.

기본 구조는 요일, 날짜, 시간입니다. 필요하면 시간대도 붙일 수 있습니다. 날짜나 시간 일부를 생략하면 systemd가 기본값을 보완하고, 초 단위를 쓰지 않으면 :00이 붙는 방식으로 해석됩니다.

[Unit]
Description=Run daily cleanup

[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true

[Install]
WantedBy=timers.target

위 예시는 매일 03:30:00에 timer가 elapse되도록 지정한 형태입니다. timer가 실제로 실행하는 대상은 기본적으로 같은 이름의 .service unit입니다. 예를 들어 cleanup.timer는 별도 Unit=을 쓰지 않으면 cleanup.service를 활성화합니다.

자주 쓰는 표현식은 어떻게 읽을까

systemd.time 문서는 daily, weekly, monthly 같은 축약 표현과 더 자세한 날짜 표현을 함께 정의합니다. 단순한 주기라면 축약 표현이 읽기 쉽고, 업무일이나 특정 시각이 중요하면 명시 표현이 낫습니다.

표현식 의미 적합한 경우
daily 매일 00:00:00 자정 기준 일일 작업
weekly 매주 월요일 00:00:00 요일보다 주 단위 반복이 중요한 작업
*-*-* 03:30:00 매일 03:30:00 정확한 실행 시각을 문서화해야 하는 작업
Mon..Fri *-*-* 09:00:00 월요일부터 금요일 09:00:00 평일 업무 시간 기준 작업
*-*-01 04:00:00 매월 1일 04:00:00 월간 집계나 정리 작업

여러 OnCalendar= 줄을 둘 수도 있습니다. 공식 문서 기준으로 같은 timer unit 안에 여러 calendar 표현식이 있으면 그중 어느 하나가 도달했을 때 timer가 동작합니다.

정확한 시각에 바로 실행될까

OnCalendar=에 쓴 시각이 실제 프로세스 시작 시각과 항상 같은 것은 아닙니다. systemd timer는 기본적으로 AccuracySec=의 영향을 받습니다. 공식 문서 기준 기본값은 1min이며, 이 시간 창 안에서 timer 이벤트를 모아 CPU wake-up을 줄일 수 있습니다.

RandomizedDelaySec=는 목적이 다릅니다. 이 값은 정해진 다음 elapse 시각 위에 무작위 지연을 더해 비슷한 timer들이 동시에 몰리는 것을 줄입니다. 여러 서버나 여러 작업이 같은 시각에 외부 서비스를 호출한다면 지연 분산이 도움이 될 수 있습니다.

설정 역할 기준
AccuracySec= 허용 정확도 창 지정 정확한 초 단위 실행이 필요한지, wake-up 최적화가 중요한지
RandomizedDelaySec= 실행 시각을 무작위로 늦춤 동시에 몰리는 작업을 분산해야 하는지
FixedRandomDelay= 무작위 지연을 안정적으로 고정 반복 실행마다 흔들림을 줄여야 하는지
RandomizedOffsetSec= calendar timer에 안정적인 offset 적용 재시작 뒤에도 주기성을 유지하며 분산해야 하는지

따라서 정확도가 중요한 짧은 테스트 timer라면 AccuracySec=1s나 더 작은 값을 검토할 수 있습니다. 반대로 백업, 캐시 정리, 통계 수집처럼 몇 분 차이가 문제가 되지 않는 작업은 기본값이나 더 넓은 정확도 창을 두는 편이 자연스럽습니다.

Persistent=true는 언제 필요할까

Persistent=true는 calendar timer에서 놓친 실행을 따라잡기 위한 설정입니다. 공식 문서 기준으로 timer가 비활성 상태였던 동안 서비스가 적어도 한 번 실행됐어야 하는 상황이면, timer가 다시 활성화될 때 서비스를 즉시 트리거할 수 있습니다. 이 동작은 OnCalendar= timer에만 효과가 있습니다.

예를 들어 노트북이나 소형 서버가 꺼져 있는 동안 매일 새벽 작업 시간이 지나갔다면, 다음 부팅 뒤 한 번 실행되게 하고 싶을 수 있습니다. 그런 작업에는 Persistent=true가 맞습니다. 반대로 오래 지난 작업을 부팅 직후 실행하면 안 되는 알림, 외부 호출, 시간 민감 작업이라면 기본값인 false가 더 안전할 수 있습니다.

적용 전에는 어떻게 검증할까

systemd-analyze calendarOnCalendar=에 넣을 표현식을 파싱하고 정규화하며 다음 elapse 시각을 계산합니다. 공식 systemd-analyze 문서 기준으로 --iterations=를 쓰면 다음 여러 번의 실행 시각을 확인할 수 있습니다.

systemd-analyze calendar 'Mon..Fri *-*-* 09:00:00'
systemd-analyze calendar --iterations=5 '*-*-01 04:00:00'
systemctl list-timers --all

첫 번째 명령은 표현식이 의도한 시각으로 해석되는지 확인하는 데 좋습니다. 두 번째 명령은 월간 작업처럼 다음 실행 간격이 긴 timer에서 여러 실행 시점을 확인할 때 유용합니다. timer를 활성화한 뒤에는 systemctl list-timers --all로 다음 실행 시각과 연결된 unit을 확인합니다.

OnCalendar와 monotonic timer는 어떻게 다를까

OnCalendar=는 날짜와 시각을 기준으로 합니다. 반면 OnBootSec=, OnStartupSec=, OnUnitActiveSec=, OnUnitInactiveSec=는 특정 기준점에서 지난 시간을 기준으로 합니다. 공식 문서는 이런 값을 monotonic timer로 설명합니다.

목적 권장 기준 예시
매일 특정 시각 실행 OnCalendar= *-*-* 03:30:00
부팅 후 일정 시간 뒤 실행 OnBootSec= OnBootSec=10min
마지막 실행 후 반복 OnUnitActiveSec= OnUnitActiveSec=1h
서비스가 끝난 뒤 간격 유지 OnUnitInactiveSec= OnUnitInactiveSec=30min

둘을 같은 timer unit에서 함께 쓸 수도 있지만, 읽기 어려워질 수 있습니다. 특별한 이유가 없다면 하나의 timer가 어떤 기준으로 실행되는지 명확하게 유지하는 편이 운영 중 확인하기 쉽습니다.

자주 묻는 질문

daily는 매일 현재 시각 기준일까

아닙니다. systemd.time 문서 기준으로 daily*-*-* 00:00:00의 축약 표현입니다. 매일 특정 시각을 원하면 직접 시각을 적는 편이 명확합니다.

컴퓨터가 잠들어 있으면 실행이 사라질까

calendar timer는 suspend 중에도 realtime clock이 멈추지 않는다는 점을 전제로 동작합니다. 공식 문서 기준으로 suspend 중 calendar timer가 elapse되면 재개 후 처리될 수 있으며, 계속 잠든 동안 여러 번 elapse되었더라도 서비스 활성화는 한 번으로 이어집니다. 시스템을 깨워야 한다면 하드웨어 지원 조건 아래 WakeSystem=을 검토합니다.

timer 파일만 만들면 바로 동작할까

아닙니다. timer가 활성화할 service unit이 필요합니다. 기본적으로 같은 이름의 .service가 대상이며, 다른 unit을 실행하려면 Unit=으로 명시합니다. 그리고 부팅 후에도 유지하려면 보통 timer unit을 enable --now로 활성화합니다.

정리

OnCalendar=는 systemd timer에서 날짜와 시각 기준 작업을 정의하는 설정입니다. 표현식 자체보다 중요한 것은 실제 실행 시각이 AccuracySec=, RandomizedDelaySec=, Persistent= 같은 옵션의 영향을 받을 수 있다는 점입니다.

무난한 기준은 세 가지입니다. 먼저 systemd-analyze calendar로 시간식을 검증합니다. 다음으로 놓친 실행을 따라잡아야 하는 작업에만 Persistent=true를 둡니다. 마지막으로 여러 작업이 동시에 몰릴 수 있으면 지연 분산 옵션을 검토합니다. 이렇게 잡으면 cron에서 넘어온 일정도 systemd timer의 동작 방식에 맞게 운영할 수 있습니다.

반응형
페이스북으로 공유카카오톡으로 공유카카오스토리로 공유트위터로 공유URL 복사