跳转到内容
搜索 AlmaLinux 文档

    浏览当前文档目录

    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 用户态,内核相关结论需真机复核。

    crontabOnCalendar
    * * * * **:0/1(每分钟)
    0 * * * *hourly 或 *-*-* *:00:00
    30 2 * * **-*-* 02:30:00
    0 3 * * 1Mon *-*-* 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 属语法映射,未逐条执行。

    /etc/systemd/system/lab-tick.service
    [Unit]
    Description=lab tick
    [Service]
    Type=oneshot
    ExecStart=/usr/local/bin/lab-tick.sh
    /etc/systemd/system/lab-tick.timer
    [Timer]
    OnCalendar=*:0/1
    Persistent=true
    [Install]
    WantedBy=timers.target
    Terminal window
    sudo systemctl daemon-reload
    sudo systemctl enable --now lab-tick.timer
    systemctl list-timers --all | grep -E "lab-tick|NEXT"
    NEXT LEFT LAST PASSED UNIT ACTIVATES
    Tue 2026-10-20 11:33:00 UTC 45s - - lab-tick.timer lab-tick.service

    同名规则:lab-tick.timer 只触发 lab-tick.service。

    Persistent=true 会在开机后补跑一次错过的任务,而不是按错过次数补。它依赖 timer 的状态文件(实测该目录存在:/var/lib/systemd/timers,权限 drwxr-xr-x root root),所以别随意清空。

    对备份类任务是好事;对「必须严格整点执行」的任务,要用 AccuracySec=1s 并接受错过就是错过。

    Terminal window
    systemctl status lab-tick.timer --no-pager
    systemctl list-timers --all | grep lab-tick
    journalctl -u lab-tick.service --no-pager | tail -5
    systemd-analyze calendar '*:0/1'

    四步分别确认:timer 是否 active、排期是否存在、service 有没有被触发、表达式是否符合预期。先看 timer 再看 service,顺序反了容易误判成脚本问题。

    • AccuracySec=1s:把默认的 1 分钟精度收紧(更准时,但更耗电/更易同时触发);
    • RandomizedDelaySec=30s:在一批机器上打散同时触发;
    • OnBootSec= / OnUnitActiveSec=:相对计时,适合「开机后 10 分钟跑一次」。
    • 只 enable service:timer 不启动;
    • 名字不一致:timer 找不到对应 service;
    • OnCalendar 时区:默认跟随系统时区,跨时区部署要显式确认。

    原 cron:30 2 * * * /usr/local/bin/backup.sh

    Terminal window
    sudo tee /etc/systemd/system/lab-backup.service >/dev/null <<'EOF'
    [Unit]
    Description=lab backup
    [Service]
    Type=oneshot
    ExecStart=/usr/local/bin/backup.sh
    EOF
    sudo tee /etc/systemd/system/lab-backup.timer >/dev/null <<'EOF'
    [Timer]
    OnCalendar=*-*-* 02:30:00
    Persistent=true
    [Install]
    WantedBy=timers.target
    EOF
    sudo systemctl daemon-reload && sudo systemctl enable --now lab-backup.timer
    systemd-analyze calendar '*-*-* 02:30:00'
    systemctl list-timers lab-backup.timer

    检查:

    1. systemd-analyze calendar 输出的下一次时间是明天 02:30
    2. list-timers 有 lab-backup.timer 且 NEXT 正确
    3. systemctl status 为 active (waiting)
    4. 手动 systemctl start lab-backup.service 能跑通脚本

    常见问题

    timer 和 cron 能同时用吗?

    能,但同一任务不要两套都配,否则会重复执行;迁移期建议先 disable cron 再启用 timer,并观察一轮日志。

    怎么确认 Persistent 真的补跑了?

    看 journalctl -u <service> 的时间戳是否在开机后立即出现一次;同时 /var/lib/systemd/timers/ 下有对应 stamp 文件。

    OnCalendar 的时区怎么定?

    默认用系统时区;容器或跨时区主机上先用 timedatectl 确认,再写表达式,避免「差 8 小时」的经典问题。