用定时器驱动备份
systemd timer 是 cron 的现代替代:一个 .timer 定义触发时间,一个配套的 .service 定义要执行的命令。相比 cron,它支持错过的任务开机补跑、随机延迟错峰、依赖关系与资源限制,日志统一进 journald,排错时可以直接看某次执行的完整输出。
基本信息
| 适用平台 | 使用 systemd 的 Linux(CentOS 7+/Ubuntu 16.04+ 等) |
|---|---|
| 权限要求 | 写 /etc/systemd/system 需 root;用户级可放 ~/.config/systemd/user |
| 时间语法 | OnCalendar 支持星期、日期与区间,如 Mon..Fri *-*-* 02:30:00 |
| 常用命令 | systemctl enable --now、list-timers、journalctl -u |
典型使用场景
- 每日固定窗口跑备份脚本,失败时从 journalctl 直接看输出
- 笔记本或虚拟机上错过执行时间的任务,开机后自动补跑
- 多台机器同一时间点的备份任务加随机延迟,避开存储端拥塞
- 长耗时任务用 Type=oneshot 串接多个 ExecStart,按顺序执行
- 失败时通过 OnFailure 触发告警单元,而不是只留一条日志
服务与定时器
服务与定时器
# /etc/systemd/system/backup.service
[Unit]
Description=nightly backup
OnFailure=backup-alert@%n.service # 失败时触发告警单元
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
Nice=10 # 备份让出 CPU 优先级
# /etc/systemd/system/backup.timer
[Unit]
Description=run backup daily
[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true # 错过则开机后补跑
RandomizedDelaySec=300
[Install]
WantedBy=timers.target启用与排查
启用与排查
systemd-analyze calendar 'Mon..Fri *-*-* 02:30:00' # 先验证语法与下次触发时间
systemctl daemon-reload # 改单元文件后必须重载
systemctl enable --now backup.timer # 启用并立即生效
systemctl list-timers --all | grep backup # 查看上次与下次触发时间
journalctl -u backup.service --since today # 查看本次执行输出
systemctl start backup.service # 手动跑一次做验证list-timers 逐列读法
| 列 | 含义 | 异常表现 |
|---|---|---|
| NEXT | 下次触发时间 | 显示 n/a 说明定时器未启用或表达式无匹配时刻 |
| LAST | 上次实际触发时间 | 长期为空说明从未成功触发,重点查单元名与启用状态 |
| PASSED | 距上次触发已过时长 | 明显超过执行周期说明错过了多轮 |
| UNIT | 对应的定时器单元 | 与预期不符说明启用了同名的旧文件 |
| ACTIVATES | 被触发的服务单元 | 指向的单元不存在时触发即失败,journalctl 里报 not found |
OnCalendar 的日期语法容易写错,用 systemd-analyze calendar 打印下次触发时间是最省事的自检;RandomizedDelaySec 会在触发点后随机推迟,实际执行时间不等于配置时间。
同一个脚本既可能被定时器触发、也可能被运维手工执行:脚本内应加锁(如 flock)与幂等判断,避免两次实例同时写同一份备份产物。服务单元里用 User= 指定运行账号,比让 root 直接跑整个备份脚本更可控。