systemd timer 默认不保证精确触发,因设计侧重负载均衡与可靠性而非实时性;OnCalendar 受 AccuracySec(默认60s)和RandomizedDelaySec影响,weekly/monthly基于日历计算首个匹配时刻;Persistent=true可补漏单次错过,配合OnUnitInactiveSec=1d实现每日至少执行一次。

systemd timer 的延迟执行和精度问题,主要源于其设计目标并非实时调度,而是兼顾系统负载、电源管理与服务可靠性。默认情况下,timer 不会严格按秒级甚至分钟级触发,尤其在系统休眠、高负载或服务未激活时,容易出现延迟甚至跳过执行。
OnCalendar 时间表达式的精度陷阱
systemd 的 OnCalendar 支持类似 cron 的时间语法,但底层实现不同:它基于 monotonic 和 realtime 时钟混合判断,且受 AccuracySec 和 RandomizedDelaySec 影响。
- 写成 red">*-*-* 02:00:00 并不等于“每天凌晨2点整触发”——实际可能延后最多 AccuracySec(默认60秒)
- 若省略秒字段(如 02:00),systemd 会自动补为 02:00:00,但依然受 AccuracySec 约束
- 使用 weekly、monthly 等关键词时,触发时间是基于日历计算的“首个匹配时刻”,不是固定偏移;例如 weekly 总在周一 00:00 触发,哪怕 timer 是周三启用的
错过执行(Missed Trigger)的常见原因与应对
当 timer unit 被禁用、系统关机/休眠、或对应 service 处于 failed 状态时,下一次 OnCalendar 到达前若条件不满足,该次触发即被跳过——systemd 默认不“补跑”。
- 启用 Persistent=true 可让 timer 在下次启动时检查是否遗漏了最近一次触发,并立即运行对应 service(仅对已过期的单次有效,不累积多次)
- 注意:Persistent 对 OnUnitActiveSec 或 OnBootSec 类型无效,只作用于 OnCalendar 和 OnClockChange
- 若需强保证“至少每日执行一次”,建议搭配 OnUnitInactiveSec=1d 作为兜底(配合 Persistent),避免因某天完全 missed 导致断更
提升定时精度的关键配置项
真正影响“准点度”的不是 OnCalendar 写法本身,而是 timer unit 中几个易被忽略的选项:
- AccuracySec=1s:将最大容忍延迟从默认 60s 降至 1 秒(仍非硬实时,但对多数运维任务足够)
- RandomizedDelaySec=0:关闭随机抖动(默认关闭,但显式设为 0 更明确)
- StartLimitIntervalSec=0:避免因频繁失败触发速率限制,间接导致延迟
- 确保对应 service 的 Type=oneshot 且无 RemainAfterExit=yes 冗余设置,否则 timer 可能误判 service 仍在运行而跳过下次启动
验证与调试技巧
不要只看 systemctl list-timers 显示的 “NEXT” 时间——它只是预测值,未必反映真实行为。
- 用 systemctl status your.timer 查看 Last Trigger 和 Triggered 字段,确认是否真有执行记录
- 启用日志追踪:systemctl enable --now your.timer 后,执行 journalctl -u your.service -u your.timer -f 实时观察触发与启动过程
- 测试 missed 行为:手动停用 timer → 等待 OnCalendar 时间过去 → 重新 enable → 检查是否触发(需 Persistent=true 才生效)










