systemd timer 延迟执行或错过的精度与 OnCalendar 配置注意

12次阅读

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

systemd timer 延迟执行或错过的精度与 OnCalendar 配置注意

systemd timer 的延迟执行和精度问题,主要源于其设计目标并非实时调度,而是兼顾系统负载、电源管理与服务可靠性。默认情况下,timer 不会严格按秒级甚至分钟级触发,尤其在系统休眠、高负载或服务未激活时,容易出现延迟甚至跳过执行。

OnCalendar 时间表达式的精度陷阱

systemd 的 OnCalendar 支持类似 cron 的时间语法,但底层实现不同:它基于 monotonic 和 realtime 时钟混合判断,且受 AccuracySecRandomizedDelaySec 影响。

  • 写成 red”>*-*-* 02:00:00 并不等于“每天凌晨2点整触发”——实际可能延后最多 AccuracySec(默认60秒)
  • 若省略秒字段(如 02:00),systemd 会自动补为 02:00:00,但依然受 AccuracySec 约束
  • 使用 weeklymonthly 等关键词时,触发时间是基于日历计算的“首个匹配时刻”,不是固定偏移;例如 weekly 总在周一 00:00 触发,哪怕 timer 是周三启用的

错过执行(Missed Trigger)的常见原因与应对

当 timer unit 被禁用、系统关机/休眠、或对应 service 处于 failed 状态时,下一次 OnCalendar 到达前若条件不满足,该次触发即被跳过——systemd 默认不“补跑”。

  • 启用 Persistent=true 可让 timer 在下次启动时检查是否遗漏了最近一次触发,并立即运行对应 service(仅对已过期的单次有效,不累积多次)
  • 注意:PersistentOnUnitActiveSecOnBootSec 类型无效,只作用于 OnCalendarOnClockChange
  • 若需强保证“至少每日执行一次”,建议搭配 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 才生效)
text=ZqhQzanResources