如何监控定时任务(Cron Job)是否正确执行?

定时任务监控(心跳监控)原理:任务成功后向监控端点发一次请求,没收到就告警。备份漏跑、报表失败第一时间知道,附脚本改造示例与实现方案。

最佳实践
如何监控定时任务(Cron Job)是否正确执行?技术指南封面

数据库备份、对账任务、邮件群发——这些定时任务(cron job)的可怕之处在于它们失败时通常悄无声息。没有用户投诉,没有错误页面,只是在三个月后需要恢复备份时,发现备份从三个月前就没再成功过。定时任务监控(也叫心跳监控)解决的就是这个盲区。

心跳监控的原理

思路反直觉但极有效:不去监控"任务失败了",而是监控"任务成功过"

  1. 为每个定时任务创建一个心跳监控端点(一个唯一 URL);
  2. 在任务脚本的最后一步(确认成功后)向该 URL 发一个请求;
  3. 监控端按任务的计划周期(如每天一次)等待这个"心跳"——超过预期窗口没收到,立即告警。

为什么这样设计?因为失败的方式千奇百怪:脚本报错、机器宕机、cron 服务停了、磁盘满了……不可能穷举每种失败去检测。但"成功"只有一种——所以监控成功的缺席,就覆盖了所有失败模式,包括最阴险的"任务根本没被触发"。

改造你的任务脚本

以数据库备份脚本为例,在成功路径的末尾加一行心跳请求:

#!/usr/bin/env bash
set -o errexit    # 任何一步失败即退出,心跳不会发出

date=`date "+%Y-%m-%d_%H:%M:%S"`
file="/dumps/mydb.$date.dump"

pg_dump mydb > "$file"
aws s3 cp "$file" s3://my-backups/
rm "$file"

# 全部成功后才发心跳
curl -fsS "https://你的心跳端点/唯一标识"

要点:

  • 心跳放在最后一步,且脚本用 set -e 确保失败即退出——中间任何环节挂了,心跳都不会发出;
  • 心跳请求本身用 -f(失败返回非零)但不要影响主流程;
  • 配置时设好宽限期(grace period):任务偶尔慢几分钟很正常,宽限期防止误报。

进阶:把执行结果也带上来

更进一步的心跳还能携带元信息:本次处理了多少行、耗时多久、退出码是多少。这些数据让监控从"跑没跑"升级到"跑得对不对"——任务成功执行但处理了 0 行数据,同样值得告警。

通用性:不只 cron

心跳模式适用于一切周期性任务:crontab、systemd timer、K8s CronJob、Windows 任务计划、Airflow DAG、宝塔计划任务……只要任务能发出一个 HTTP 请求,就能纳入监控。对不能改代码的系统任务,也可以用包一层脚本的方式加心跳。

观测云对照

观测云支持用心跳式监控覆盖定时任务:任务完成后向指定地址发请求,监控器按预设周期检查心跳是否按时到达,缺席即按钉钉/企微/飞书/电话分级告警。也可以走另一条路:任务日志统一采集后,对"预期时间窗口内无成功日志"配置无数据告警,两种方式殊途同归。对关键任务,建议心跳 + 日志双保险——前者防静默,后者留现场。

常见问题(FAQ)

Q:心跳监控和传统的"错误日志告警"选哪个?
A:都要。错误日志告警覆盖"跑了但报错",心跳覆盖"根本没跑"(机器宕机、cron 停了、配置丢了)。后者恰恰是最难被发现的失败模式。

Q:任务每小时跑但时长不定,怎么设宽限期?
A:宽限期设为最长预期耗时的 1.5-2 倍。比如任务通常 5 分钟跑完、偶尔 15 分钟,宽限设 20-30 分钟。

Q:K8s CronJob 怎么接?
A:Job 容器里执行完主逻辑后 curl 心跳端点即可;也可以利用 K8s 的 Job 状态指标,监控"预期时间窗口内没有成功的 Job 完成事件"。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台