AlmaLinux 10:从 cron 迁到 systemd timer 的对照与调试
在 AlmaLinux 10.2 特权容器(systemd 257)中实测:建 lab-tick.service/lab-tick.timer、enable --now、list-timers、手动 start、disable。日志:plans/content-expansion/evidence/logs/alma-systemd-timers.log。
容器共享宿主内核(5.14);systemd 是真实 EL10 用户态,内核相关结论需真机复核。
crontab 与 OnCalendar 对照
Section titled “crontab 与 OnCalendar 对照”| crontab | OnCalendar |
|---|---|
* * * * * | *:0/1(每分钟) |
0 * * * * | hourly 或 *-*-* *:00:00 |
30 2 * * * | *-*-* 02:30:00 |
0 3 * * 1 | Mon *-*-* 03:00:00 |
@reboot | 用 WantedBy=multi-user.target 的 oneshot service |
systemd-analyze calendar '<表达式>' 会把表达式翻译成下一次触发时间。上表里 *:0/1、*-*-* 02:30:00、Mon *-*-* 03:00:00 三条已在 EL10 上实测(输出含 Normalized form 与 Next elapse),hourly 与 @reboot 属语法映射,未逐条执行。
两个文件与启用
Section titled “两个文件与启用”[Unit]Description=lab tick[Service]Type=oneshotExecStart=/usr/local/bin/lab-tick.sh[Timer]OnCalendar=*:0/1Persistent=true[Install]WantedBy=timers.targetsudo systemctl daemon-reloadsudo systemctl enable --now lab-tick.timersystemctl list-timers --all | grep -E "lab-tick|NEXT"NEXT LEFT LAST PASSED UNIT ACTIVATESTue 2026-10-20 11:33:00 UTC 45s - - lab-tick.timer lab-tick.service同名规则:lab-tick.timer 只触发 lab-tick.service。
Persistent:关机期间错过的任务
Section titled “Persistent:关机期间错过的任务”Persistent=true 会在开机后补跑一次错过的任务,而不是按错过次数补。它依赖 timer 的状态文件(实测该目录存在:/var/lib/systemd/timers,权限 drwxr-xr-x root root),所以别随意清空。
对备份类任务是好事;对「必须严格整点执行」的任务,要用 AccuracySec=1s 并接受错过就是错过。
到点不跑的排查顺序
Section titled “到点不跑的排查顺序”systemctl status lab-tick.timer --no-pagersystemctl list-timers --all | grep lab-tickjournalctl -u lab-tick.service --no-pager | tail -5systemd-analyze calendar '*:0/1'四步分别确认:timer 是否 active、排期是否存在、service 有没有被触发、表达式是否符合预期。先看 timer 再看 service,顺序反了容易误判成脚本问题。
AccuracySec=1s:把默认的 1 分钟精度收紧(更准时,但更耗电/更易同时触发);RandomizedDelaySec=30s:在一批机器上打散同时触发;OnBootSec=/OnUnitActiveSec=:相对计时,适合「开机后 10 分钟跑一次」。
- 只 enable service:timer 不启动;
- 名字不一致:timer 找不到对应 service;
- OnCalendar 时区:默认跟随系统时区,跨时区部署要显式确认。
练习:把一条 cron 迁成 timer
Section titled “练习:把一条 cron 迁成 timer”原 cron:30 2 * * * /usr/local/bin/backup.sh
sudo tee /etc/systemd/system/lab-backup.service >/dev/null <<'EOF'[Unit]Description=lab backup[Service]Type=oneshotExecStart=/usr/local/bin/backup.shEOFsudo tee /etc/systemd/system/lab-backup.timer >/dev/null <<'EOF'[Timer]OnCalendar=*-*-* 02:30:00Persistent=true[Install]WantedBy=timers.targetEOFsudo systemctl daemon-reload && sudo systemctl enable --now lab-backup.timersystemd-analyze calendar '*-*-* 02:30:00'systemctl list-timers lab-backup.timer检查:
systemd-analyze calendar输出的下一次时间是明天 02:30list-timers有lab-backup.timer且 NEXT 正确systemctl status为active (waiting)- 手动
systemctl start lab-backup.service能跑通脚本
常见问题
timer 和 cron 能同时用吗?
能,但同一任务不要两套都配,否则会重复执行;迁移期建议先 disable cron 再启用 timer,并观察一轮日志。
怎么确认 Persistent 真的补跑了?
看 journalctl -u <service> 的时间戳是否在开机后立即出现一次;同时 /var/lib/systemd/timers/ 下有对应 stamp 文件。
OnCalendar 的时区怎么定?
默认用系统时区;容器或跨时区主机上先用 timedatectl 确认,再写表达式,避免「差 8 小时」的经典问题。
- 日志轮转:logrotate 实战
- 重启策略:重启策略
- 防火墙规则:firewalld rich rule