systemd 定时器到点不触发?按这五个地方查

举报
yd_242458115 发表于 2026/11/06 08:04:44 2026/11/06
【摘要】 定时器配好了、list-timers 也显示下次触发时间,到点却什么都没发生。按命中率从高到低排五个原因:OnCalendar 星期几写法、Persistent 管不了什么、oneshot 下 RuntimeMaxSec 无效(要用 TimeoutStartSec)、服务名与定时器名不匹配、RandomizedDelaySec 把到点变成大概到点。附排查顺序表与心跳文件方案。

定时器明明配了,systemctl list-timers 也显示下次触发时间,到点却什么都没发生。这类问题排查起来很折磨,因为 systemd 不会主动告诉你"我为什么没跑"。下面五个地方按命中率从高到低排。

一、OnCalendar 的星期几写法最容易错

systemd-analyze calendar "Mon..Fri 09:00"

输出里会给你 Next elapse 和 UTC 两个时间。如果这条命令报错,定时器一定不会触发,不用再往下查了。

顺带提醒:OnCalendar=daily 的默认时间是本地 00:00,不是"每天随便什么时候"。想要随机分布得配 RandomizedDelaySec。

二、Persistent=true 不是万能补药

很多人以为加上 Persistent=true 就万事大吉。它的作用只是:机器关机期间错过的触发点,开机后补跑一次。它管不了三件事:

  • 服务本身失败(需要用 OnFailure= 挂一个告警单元)
  • 触发点比当前时间早(新建的定时器不会立刻跑,要等到下一个触发点)
  • ConditionXXX 不满足被跳过

最后一条坑最深:Condition 判断失败时,systemctl status 显示的是 inactive (dead),跟"没被触发"长得一模一样。要看真正原因得用:

journalctl -u 你的服务名 -b --no-pager | grep -i condition

三、Type=oneshot 下 RuntimeMaxSec 是无效的

这是我在一个跑两小时的任务上踩过的坑。当时给服务加了 RuntimeMaxSec=600 想限制最长运行时间,结果进程跑了 3 小时也没被杀。

原因是 RuntimeMaxSec 只对 Type=simple(以及 notify、exec)生效。Type=oneshot 的服务,systemd 只在启动阶段盯着,启动完成后的运行时长它不管。要给 oneshot 限时,得用:

TimeoutStartSec=600

区别在于:RuntimeMaxSec 超时算"运行超时",TimeoutStartSec 超时算"启动失败",后者会让服务状态变成 failed,能被监控抓到。对我们来说这反而是想要的效果。

四、服务名和定时器名不一致

[Timer]
Unit=foo-daily.service

漏了这行,定时器会去找一个不存在的 foo.service,然后静默失败。list-timers 里照样显示下次触发时间,照样到点触发,只是触发的目标不存在。

用这条命令快速核对对应关系:

systemctl list-timers --all

看 ACTIVATES 那一列,就是你实际会触发谁。

五、RandomizedDelaySec 让"到点"变成"大概到点"

配了 RandomizedDelaySec=30m 之后,触发时间会往后随机推 0 到 30 分钟。这是设计行为,用来避免一批机器同一秒打爆后端。

问题在于:如果你的监控盯着"09:00 后 5 分钟必须有新日志",就会被这个随机延迟误报。要么把监控窗口放宽到延迟上限之外,要么干脆别在关键任务上用随机延迟。

排查顺序总结

顺序检查什么命令
1表达式语法对不对systemd-analyze calendar "..."
2触发的目标单元在不在systemctl list-timers --all 看 ACTIVATES
3服务是不是被 Condition 跳过`journalctl -u 服务名 -b \grep -i condition`
4oneshot 有没有被限时需求用 TimeoutStartSec 而不是 RuntimeMaxSec
5时间点是不是被随机延迟推后看 RandomizedDelaySec

一个通用建议

给定时任务加一个"心跳"文件:服务成功结束时 touch 一个时间戳文件,监控只看这个文件的 mtime。比盯 journald 日志可靠得多,因为日志会被轮转、会被你我手滑删掉,而心跳文件是任务自己写的,最诚实。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。