为什么你的 Cron 作业会静默失败(以及如何修复)

发布: (2026年3月7日 GMT+8 06:37)
6 分钟阅读
原文: Dev.to

Source: Dev.to

您的数据库备份每晚在凌晨 2 点运行。您的发票生成器每周一上午触发。您的缓存预热程序每五分钟运行一次。它们都运行良好——直到出现问题。

Cron 任务的问题在于,它们的失败方式和运行方式一样:静默。没有人在凌晨 2 点查看 stdout。也没有浏览器来显示错误页面。当 cron 任务停止工作时,唯一的信号就是没有任何动作发生。

您在周五下午发现备份自周二以来就没有运行。客户给您发邮件,因为他们的每周报告从未送达。或者您的磁盘因清理任务在三周前死亡而被填满。

为什么 Cron 任务会静默失败

常见原因

  • 服务器重启 – 重启后,cron 通常会重新启动,但如果你的任务依赖已挂载的卷、正在运行的数据库或需要几秒钟才能初始化的网络连接,重启后第一次运行会静默失败。
  • 磁盘已满 – 任务尝试写入临时文件或日志条目但失败,导致崩溃。Cron 并不在意。
  • 依赖失败 – 你调用的 API 宕机、数据库连接超时,或 S3 存储桶策略被修改。任务抛出异常并以非零代码退出;无人注意。
  • 时区问题 – 你将服务部署在 UTC 时区,但编写 cron 表达式时假设是美国东部时间。任务会在错误的时间运行,或者在夏令时切换期间运行两次——甚至根本不运行。
  • 提前崩溃 – 如果你的错误处理依赖任务运行足够长时间以到达 catch 块,早期的段错误或 OOM 杀死会留下零痕迹。

为什么传统监控会漏掉它们

大多数监控工具关注 主动 症状:CPU 高、响应慢、错误率激增。它们擅长检测正在发生的事情。

Cron 任务的失败是 被动 的——某事未发生。你的 APM 不会提醒脚本未运行,错误追踪器也无法捕获从未启动的进程抛出的异常。

Source:

解决方案:颠倒模型

与其监控失败,不如 监控成功的缺失。这本质上是一种 dead‑man’s switchheartbeat monitoring

  1. 创建一个监控,设定预期的间隔(例如,“每 24 小时”)。
  2. 在作业的末尾添加一次 ping
  3. 如果 ping 未能及时到达,则触发警报。

关键洞察:你监控的不是作业是否失败,而是它是否成功。如果没有收到它的信号,就说明出现了问题——你不需要确切知道是什么导致的。

实现的简易方式是:在脚本的末尾添加一次 HTTP 请求。如果脚本成功完成,ping 会被发送;如果脚本崩溃、卡死或根本未启动,ping 就不会到达,你将收到警报。

实现示例

Bash

#!/bin/bash
# backup-database.sh

set -e  # Exit on any error

pg_dump "$DATABASE_URL" | gzip > /tmp/backup.sql.gz
aws s3 cp /tmp/backup.sql.gz s3://my-backups/$(date +%Y-%m-%d).sql.gz
rm /tmp/backup.sql.gz

# Report success
curl -fsS --retry 3 https://pulsemon.dev/api/ping/nightly-backup

set -e 标志会在出现任何错误时退出脚本。curl 仅在上述所有操作成功时执行;否则不会发送 ping。

Python

import requests

def main():
    # ... your job logic here ...
    run_etl_pipeline()
    requests.get("https://pulsemon.dev/api/ping/nightly-etl", timeout=10)

if __name__ == "__main__":
    main()

Node.js

const fetch = require('node-fetch');

async function main() {
  // ... your job logic here ...
  await processQueue();
  await fetch('https://pulsemon.dev/api/ping/queue-processor');
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});

需要心跳监控的典型无人值守进程

  • Database backups – 最常见的静默故障。
  • Email queues – 停止处理后,没人会在几天内抱怨,因为他们认为这很正常。
  • Data syncs between services – 过时的分析仪表盘乍看之下仍然正常。
  • Certificate renewals (e.g., Let’s Encrypt) – 证书过期会触发令人恐慌的浏览器警告。
  • Cleanup jobs that free disk space – 当它们停止时,其他服务会开始崩溃。

如果这些进程在你的基础设施上运行,就应该配置心跳监控。设置它所需的时间远远少于恢复故障的时间。

试用 PulseMon

我构建了 PulseMon 来为我的项目解决这个问题。如果你想尝试,它提供了包含 30 个监视器的免费套餐:

PulseMon.dev

0 浏览
Back to Blog

相关文章

阅读更多 »