未来星球 未来星球
  • 首页
  • 新闻资讯
  • 技术教程
  • 软件工具
  • 知识百科
  • 生活实用
  • 个人随笔
  • 生命外星人
首页 › 技术教程 › 用 systemd timer 替代 cron:失败重试、日志与错峰执行的完整配置
  • 0
  • 0

用 systemd timer 替代 cron:失败重试、日志与错峰执行的完整配置

admin
21 小时前
9 views
用 systemd timer 替代 cron:失败重试、日志与错峰执行的完整配置-未来星球

cron 能跑,但你不知道它有没有跑成功

一台跑了三年的小服务器,某天发现备份目录里最新的文件是两个月前的。查 crontab,任务还在;查日志,什么都没有。cron 最大的问题不是功能不够,是它默认沉默:成功了不说话,失败了也不说话,除非你主动把输出重定向到某个文件。

systemd timer 是同一位作者生态里的替代品。它把“什么时候跑”和“跑什么”拆成两个文件,把每次执行变成一个有状态、有日志、可查询的单元。本文给出一份可以直接抄的配置,并列出五个真实踩过的坑。

1. 什么时候该换,什么时候不必换

先说结论:如果你只是每天跑一条 rsync,cron 完全够用,换过去是给自己找麻烦。真正值得换的是这几种情况。

  • 需要知道上次执行成功还是失败,并且失败时能自动重试
  • 任务偶尔超过预期时长,需要超时保护,避免进程堆叠
  • 多个任务挤在同一时刻启动,需要错峰
  • 需要把输出进 journald,和系统其它日志放在一起查
  • 需要在开机后补跑错过的任务

2. 三个位置,先搞清楚文件放哪

systemd 的单元文件有三个常见位置,优先级从高到低:/etc/systemd/system/(管理员自定义,推荐)、/run/systemd/system/(运行时临时)、/usr/lib/systemd/system/(软件包安装,不要手改)。

用户级任务则放在 ~/.config/systemd/user/,配合 systemctl –user 使用。用户级的好处是不需要 root,坏处是用户没登录时默认不运行,要额外执行 loginctl enable-linger 才行。

3. 一份能直接用的 .service

先写执行体。文件名 backup.service,放在 /etc/systemd/system/:

[Unit]
Description=Daily backup to external disk
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
User=backup
TimeoutStartSec=2h
Nice=10
IOSchedulingClass=idle

几个要点。Type=oneshot 表示这是一次性任务,执行完就退出,不要写 simple。TimeoutStartSec 是超时上限,超过就杀掉,防止一次卡死的任务拖到第二天。Nice 和 IOSchedulingClass 用来降低优先级,备份不该和线上服务抢 IO。

4. 定时器:OnCalendar 与错峰

再写 backup.timer,同名同目录:

[Unit]
Description=Run backup daily

[Timer]
OnCalendar=*-*-* 03:30:00
RandomizedDelaySec=1800
Persistent=true
AccuracySec=1min

[Install]
WantedBy=timers.target

RandomizedDelaySec=1800 是关键一行,它让任务在 03:30 之后的半小时内随机启动。如果你有十台机器都在这时备份,不加这一行就会同时打到同一个存储上。Persistent=true 负责补跑:机器在 03:30 时是关机的,开机后会把错过的这一次补上,这正是 cron 做不到的。

OnCalendar 的写法比 cron 好读:daily 等价于每天零点,Mon..Fri 04:00 是工作日凌晨四点,*-*-1 05:00 是每月一号。要验证表达式是否正确,用 systemd-analyze calendar 直接算给你看。

systemd-analyze calendar "*-*-* 03:30:00"
systemctl daemon-reload
systemctl enable --now backup.timer
systemctl list-timers --all

5. 失败重试怎么写

systemd 本身提供重启策略,但对 oneshot 任务,Restart=on-failure 需要配合 RestartSec 才有效,而且默认只重启几次就放弃:

Restart=on-failure
RestartSec=10min
StartLimitIntervalSec=1h
StartLimitBurst=3

这段的意思是:失败后等十分钟重试,一小时内最多尝试三次。StartLimit 必须写在 [Unit] 段,写在 [Service] 里会被忽略,这是最容易出错的地方,因为 systemd 不会报错,只是静默不生效。

如果重试三次仍失败,更好的做法是让脚本自己发通知,而不是无限重启。重试解决的是瞬时故障,不是持续故障,后者重启一百次也没用。

6. 日志:别再重定向到文件

systemd 会把标准输出和标准错误自动收进 journald,不需要在脚本里写 >> /var/log/xxx.log。查最近一次执行:

journalctl -u backup.service -n 50
journalctl -u backup.service --since "24 hours ago"
systemctl status backup.service

要注意 journald 默认会限制日志体积,长期日志需要配置 SystemMaxUse 或转发到 rsyslog,否则一个月前的记录可能已经被轮转掉了。查历史失败记录时,这一步经常是决定性的。

7. 五个真实踩过的坑

第一个:环境变量不一样。cron 里的 PATH 很短,systemd 里的 PATH 也不完整。脚本里用了绝对路径还好,一旦调用 python、rsync 这类命令,最好在 service 里显式写 Environment=PATH=/usr/local/bin:/usr/bin:/bin。

第二个:工作目录不是你以为的那个。默认 WorkingDirectory 是 /,脚本里写相对路径会直接失败。加上 WorkingDirectory=/opt/backup 更稳妥。

第三个:忘了 daemon-reload。改完单元文件不执行 systemctl daemon-reload,改动不会生效,而 systemctl status 看起来一切正常。

第四个:timer 启用了,service 没被触发。常见原因是 timer 文件里没写 [Install] 段,或者用 enable 的是 service 而不是 timer。要启用的是 .timer,不是 .service。

第五个:脚本没有执行权限。ExecStart 指向的脚本必须有 x 位,否则报 203/EXEC,错误信息只有一行,很容易被当成路径写错。

8. 迁移检查清单

检查项 cron 写法 systemd 写法
执行时间 30 3 * * * OnCalendar=*-*-* 03:30:00
错峰 脚本里 sleep $RANDOM RandomizedDelaySec=1800
错过补跑 不支持 Persistent=true
失败重试 需自己写循环 Restart=on-failure
超时控制 需 timeout 命令包一层 TimeoutStartSec=2h
日志 手动重定向 journalctl -u 自动收集

迁移顺序建议:先写 service,手动 systemctl start 跑通一次,再写 timer 并 enable。反过来的话,定时器到了点没反应,你会同时怀疑两个文件。

写在最后

systemd timer 的学习成本确实比 crontab 高,一行 vs 两个文件。但它把“任务”变成了系统里的一等公民:有状态、有日志、有超时、有依赖,可以被别的单元引用。

对于每天只跑一条命令的场景,这个代价不划算。对于“必须知道它到底跑没跑成”的场景,cron 的沉默本身就是风险。


你还在用 cron 吗?有没有被“任务静默失败”坑过一次?

0

搬了五次家之后,我只剩一箱东西

上一篇

AI 新闻日报 – 2026年10月26日:动荡的二十年与五千亿美元的赌注

下一篇

评论 (0)

登录后可发布~
立即登录
暂无评论

admin

当生活给你的全是不如意,那你一定要相信自己的兴趣!
105
文章
0
评论
-11
喜欢
2026 年 10 月
一 二 三 四 五 六 日
 1234
567891011
12131415161718
19202122232425
262728293031  
« 9 月    

近期评论

聚合文章

本地处理 PDF 的五件免费工具:合并、拆分、压缩、OCR、签名
高速公路为什么大多没有路灯:一笔算得清的账
家庭应急包清单:停电、停水、受伤、暴雨,四种场景各备什么
金星磷化氢之争:一条光谱线如何被反复确认又反复推翻
一万年后的考古学家,会从地层里挖出什么
AI 新闻日报 – 2026年10月26日:动荡的二十年与五千亿美元的赌注
用 systemd timer 替代 cron:失败重试、日志与错峰执行的完整配置
搬了五次家之后,我只剩一箱东西

猜你喜欢

用 Caddy 2 做反向代理与自动 HTTPS:一份可复现的配置手册

用 Caddy 2 做反向代理与自动 HTTPS:一份可复现的配置手册

admin
14 0 0
2026年AI工具实战指南:7个免费工具让你效率翻倍

2026年AI工具实战指南:7个免费工具让你效率翻倍

admin
81 0 0
2026 年必学的 5 个 AI 提示词技巧

2026 年必学的 5 个 AI 提示词技巧

admin
89 0 0
用 WireGuard 组建家庭内网:三台设备、一份可复现的配置

用 WireGuard 组建家庭内网:三台设备、一份可复现的配置

admin
14 0 0

关于我们

你是否对浩瀚的宇宙充满好奇?你是否渴望掌握未来科技的力量?现在,机会来了!“未来星球”将带你进入奇妙世界,开启你的科技探险之旅! 这是一个充满想象和创造力的博客!

分类导航

首页 新闻资讯 技术教程 软件工具 知识百科 生活实用 个人随笔 生命外星人

友情链接

未来星球AI工具【网络版】 未来星球 pycharm官方站【中国】
Copyright © 2026 未来星球. Designed by nicetheme. 蒙ICP备2026002569号-1
  • 请到 [后台->外观->菜单] 中设置菜单
  • AI未来
  • 生活百科
  • 档案
  • 外星人
  • 未来星球

admin

当生活给你的全是不如意,那你一定要相信自己的兴趣!
105
文章
0
评论
-11
喜欢