家里服务器上有20个定时任务每天替我干活。真正吓人的不是它们不跑,而是跑了、出错了、结果没送到——我却一直蒙在鼓里。
先说结论
给定时任务装看门狗,核心就三条:
- 异常才报:状态文件去重,正常情况闭嘴
- 同一件事只报一次:版本号没变就静默
- 能自愈就不等人:小问题自动修,修不好再喊人
三个设计都是几十行shell,没有框架,没有依赖。
背景:我机上的20个定时任务
先交代现场。jobs.json里躺着20个任务,代表性几个:
| 任务 | 节奏 | 干什么 |
|---|---|---|
| 系统健康巡查 | 每天 08:05 | 巡检脚本,结果直发我 |
| 磁盘空间看门狗 | 每 120 分钟 | 磁盘/inode 异常才报 |
| 版本监控 | 每 6 小时 | 有新版本才提示 |
| 任务自动修复器 | 每 120 分钟 | 卡住的任务自动诊断修复 |
| 更新检查(RTK) | 每周一 10:00 | 检查新版本并自动升级 |
| DNS健康检查 | 每 5 分钟 | 域名解析异常告警 |
任务多了以后,两个问题浮出水面。
为什么裸定时任务不可靠
坑一:报警疲劳。
磁盘看门狗第一版,每次运行都报一遍。磁盘明明是正常的,也照样发消息。
一周之后我就麻木了。报警刷屏的结局是:真出事那天,警报混在一堆"一切正常"里,被我随手划掉。
坑二:跑了,不等于知道了。
这是更隐蔽的坑。我翻了投递记录:236条投递里,88条发送失败。
任务确实跑了,结果也生成了,但最后一步"送到我眼前"失败了。日志里的原因很统一:会话没就绪。
最惨的一次:某天早上连续4个任务投递失败,我到中午才知道当天有一堆事发生。
设计1:磁盘看门狗,异常才报
v2的核心是一个状态文件,只存一行:
| |
含义:上次已报级别0(正常),当时使用率27%。
判断逻辑:
| 当前状态 | 动作 |
|---|---|
| 级别升级(0→1、0→2、1→2) | 报警 |
| 同级别 | 静默退出 |
| 降回正常 | 报一次"已恢复" |
阈值:磁盘 ≥90% 严重,≥75% 警告;inode ≥80% 也算严重。
触发时不是干巴巴一句"磁盘满了",而是直接附上排查现场:
- 使用率和剩余空间
du排出全盘最大目录 Top8- /root 下大头 Top5
- 可清理项快照(缓存、npm、docker占用量)
实测当前状态:根分区 295G 用了 74G(27%),inode 用 5%,级别 0,静默。
关键思想:报"变化",不报"状态"。 人只对变化敏感。
设计2:版本监控,每个新tag只报一次
版本监控的烦恼不一样:它一天扫好几次,同一个版本会被反复发现。
解法还是状态文件,这次存JSON:
| |
扫到新tag时:
- 和已通知的tag比对,相同就静默退出
- 不同才算"新版本",顺带统计增量——
git log数出commit数和新特性数,一起报出来 - 报完把新tag写回状态文件
还有一条纪律:监控只负责说"有新版本"。要不要写文章、什么时候升级,是另一套节奏的事。监控和动作解耦,报警才不会变形。
设计3:自动修复器,自愈而不只是报警
前两个设计解决"报得准",第三个解决"报了之后谁来做"。
任务自动修复器每120分钟跑一轮,固定五步:发现 → 诊断 → 修复 → 放行 → 检查上轮修复结果。
修复前先分类:
| 类型 | 例子 | 处理 |
|---|---|---|
| A类 | 格式错误、错别字、可验证的事实修正 | 自动修,修完放行重审 |
| B类 | 观点争议、缺章节、验证不了的事实 | 只通知,等人决定 |
两条安全绳,防止自动修复变成自动闯祸:
- 每轮最多修3个任务
- 同一个任务累计修3次还不过,升级人工,不再重试
无限重试的自动化不是自动化,是事故放大器。 上限是必需品。
两个真实故障
设计再好,也要靠真实故障检验。这两个都是本机日志里挖出来的。
故障一:迟到1小时37分,然后失败。
更新检查排在每周一10:00。有一周它没按时跑——当天机器磁盘写满,调度器日志里躺着8条"disk is full"。
这任务直到11:37才被重新拉起,迟到1小时37分,而且拉起后还是没跑成。
结果就是:那一周的版本检查无声无息地丢了。没有报错,没有重试提示,什么都没有。
故障二:4连发失败。
另一天早上七点半到九点,连续4个任务的结果投递全部失败,原因都是会话没就绪。
4个任务都正常执行了,输出文件都在。但"我"这个终点,什么都没收到。
这两个故障指向同一件事:报警的送达环节本身也需要被监控。
任务跑了≠你知道了,中间还隔着投递这一跳。现在发送失败的内容都会落盘留底,配上兜底通道,不再静默蒸发。
可复制的做法总结
- 先有状态文件,再谈报警——一行文本就够
- 报变化,不报状态——正常情况保持沉默
- 报警带现场——附Top目录、commit数,别让人二次排查
- 自愈必须设上限——3次修不好就交给人
- 监控你的监控——投递失败也要落盘、也要能被发现
整套东西最大的一个脚本也只有64行。看门狗的价值不在技术难度,在于承认一个事实:没有状态记忆的定时任务,只是在假装可靠。
你的定时任务上一次静默失败是什么时候?翻翻日志,可能会吓一跳。