定时器精度怎么定
systemd 定时器默认不要求严格准点:它把触发时间放在一个误差窗口内合并执行,以减少系统唤醒次数、节省能耗。因此在大规模集群里,同一时刻的定时任务会被自然摊开,这通常是优点而不是缺陷。真正需要准点或需要错峰时,分别用精度参数与随机抖动参数来显式声明意图。
基本信息
| 适用平台 | systemd 发行版(定时器单元) |
|---|---|
| 默认行为 | 允许误差窗口,合并相近的唤醒时刻 |
| 精度参数 | 控制允许的误差范围,越小越准点也越耗能 |
| 抖动参数 | 在触发点之后追加随机延迟,用于错峰 |
典型使用场景
- 对账、报表必须在整点附近准点执行,需要收紧误差窗口
- 几十台机器同时执行维护任务,需要加入随机抖动错峰
- 排查「任务为什么晚了几十秒才跑」,确认是默认窗口造成
- 验证定时表达式是否符合预期,避免写错时间点
- 确认机器停机期间错过的任务是否需要补跑
配置示例
配置示例
# /etc/systemd/system/myjob.timer
[Unit]
Description=Nightly job
[Timer]
OnCalendar=*-*-* 03:00:00
AccuracySec=1s # 收紧误差窗口,接近准点触发
RandomizedDelaySec=300 # 再随机延迟 0 到 300 秒,用于错峰
Persistent=true # 停机期间错过的任务在恢复后补跑
[Install]
WantedBy=timers.target验证与排查
验证与排查
systemd-analyze calendar '*-*-* 03:00:00' # 校验表达式并看下次触发时间
systemctl list-timers myjob.timer --all # 看上次与下次触发时刻
systemctl cat myjob.timer # 确认生效的参数
journalctl -u myjob.service --since yesterday | tail -20 # 任务实际执行记录
systemctl daemon-reload && systemctl restart myjob.timer # 改完单元重新加载参数逐项读法
| 参数 | 含义 | 调整方向 |
|---|---|---|
| OnCalendar | 触发的时间表达式 | 写错不会报错,用分析命令校验 |
| AccuracySec | 允许的误差窗口 | 要准点就收紧,要省电就放宽 |
| RandomizedDelaySec | 触发后追加的随机延迟 | 错峰用,时序敏感任务不要加 |
| Persistent | 是否补跑错过的任务 | 需要不漏跑的维护任务应开启 |
| OnBootSec 等 | 相对时间触发方式 | 开机后一段时间执行,适合自愈脚本 |
随机抖动是在触发点之后追加延迟,可能让任务跨过下一个调度周期,设置时要确保延迟上限小于任务间隔。
使用建议
- 先把触发表达式用分析命令验证,再谈精度与抖动
- 单个服务准点需求用收紧误差窗口,大规模集群错峰用随机抖动
- 记录任务实际触发时刻,验证是否落在预期范围内
- 修改单元文件后重新加载并重启定时器,否则改动不生效
- 需要漏跑补偿时开启持久化,并确认补跑不会造成重复执行
默认的分钟级误差窗口在大规模集群里是有意设计,若全部改成秒级精度,会造成同一时刻的系统唤醒风暴。