systemd 定时器概览
systemd timer 是把定时任务交给 systemd 管理的方式:扩展名为 timer 的单元定义什么时候触发,同名的 service 单元定义触发后做什么。相比 cron,它精度更高、能看到上次与下次触发时间、支持错过补跑与随机延迟,输出也统一进 journal。代价是要写两个单元文件,理解成本略高。
基本信息
| 适用场景 | 用 systemd 定时器替代 cron |
|---|---|
| 组成 | 一对同名单元:name.timer 定义时间,name.service 定义动作 |
| 关键指令 | OnCalendar 日历表达式 / OnBootSec 启动后延时 / Persistent 补跑 / RandomizedDelaySec 随机延迟 / Unit 指定拉起的服务 |
| 管理与查看 | systemctl enable --now、list-timers、status 与对应 service 的 journal |
典型使用场景
- 每日备份与巡检:日历表达式比 crontab 更直观
- 多机错峰:加随机延迟,避免同一时刻一起打满后端
- 补跑错过的任务:持久化开关让开机后补上关机期间错过的那次
- 启动后延时执行:用于等待网络或依赖服务就绪
- 统一日志:任务输出自动进 journal,按单元名就能检索
timer 单元示例
timer 单元示例
# /etc/systemd/system/backup.timer
[Unit]
Description=Daily backup
[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=10m
[Install]
WantedBy=timers.target配套 service 单元
配套 service 单元
# /etc/systemd/system/backup.service
[Unit]
Description=Run backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh启用与查看
启用与查看
systemctl daemon-reload
systemctl enable --now backup.timer
systemctl list-timers --all
systemctl status backup.timer
journalctl -u backup.service -n 30关键指令
| 指令 | 作用 | 提示 |
|---|---|---|
| OnCalendar | 日历表达式 | 支持 daily、weekly 与精确时间写法 |
| OnBootSec | 启动后经过时长触发 | 用于等待依赖就绪 |
| Persistent | 补跑错过的触发 | 关机期间错过的开机后补一次 |
| RandomizedDelaySec | 随机延迟 | 多机错峰,避免同时打满后端 |
| Unit | 指定要激活的单元 | 默认取同名 service |
| AccuracySec | 触发精度窗口 | 默认窗口较宽,可收紧 |
只启用 timer 即可,配套的 service 不需要单独 enable;两者不同名时要用 Unit 明确指定要拉起哪个服务。
排查时用 list-timers 看下次触发时间,而任务失败的原因要到对应 service 单元的 journal 里找,不在 timer 单元里。
日历表达式可以先用 systemd-analyze calendar 校验,它会把下一次触发时间算出来。写复杂表达式前先验一遍,比等到夜里任务没跑再回头查划算。
触发条件写法
| 指令 | 语义 | 备注 |
|---|---|---|
| 按日历时刻 | 支持日历表达式 | 精度受默认窗口影响 |
| 单调时钟 | 相对时间点触发 | 重启后重新计时 |
| 补跑 | 错过则补执行 | 只补最近一次 |
| 随机延迟 | 时间点后抖动 | 避免同一时刻并发 |
| 依赖声明 | 触发前满足前置 | 与单元依赖配合使用 |
触发表达式要先用分析工具验证它解析出的下次触发时间:表达式写错在启用时不报错,只会到点没有任何动作,现象与「没触发」一样难查。排查顺序是先看定时器列表里的下次触发时间,再看对应服务的执行记录与退出码。