事故现场
那是一个给企业做的客资同步管道:定时从广告平台拉取线索,解密、关联投放数据,写进飞书多维表格。上线那天我盯着它跑通了三轮,数据整整齐齐地出现在表里。我宣布交付,心里想的是「这种定时任务能有什么问题」。
三周后,运营问我:某几天的客资是不是少了?
我回去查日志。定时任务失败了 22 次。没有一个人知道——包括我。服务器没崩,进程还在,cron 照常触发,只是任务内部因为一个 token 过期,每次都在第一步就报错退出。它安安静静地失败,就像它安安静静地成功一样。
沉默的失败和沉默的成功,外观上一模一样
这是整件事最扎心的地方。从外面看:
- 服务器在跑 ✓
- 进程存在 ✓
- cron 日志有触发记录 ✓
- 没有报警 ✓
四个绿灯,然而任务已经死了三周。
我后来把这个教训贴在了自己的墙上:「看起来在跑」不等于「真的在工作」。一个自动化系统如果不主动向你汇报,那么它的沉默不携带任何信息——你不能把「没消息」当成「好消息」,因为失败也是没消息的。
修复:可观测性三件套
技术修复只花了十分钟(token 自动刷新)。真正值钱的是之后加上的三样东西,我现在每个自动化项目都标配:
- 失败要告警。 任务挂了必须立刻通知到人——发飞书、发企微,随便什么,但必须「推」到人眼前,而不是等人去「拉」日志。
- 成功要心跳。 光有失败告警不够——如果告警系统本身也挂了呢?所以任务每次成功也要留一条心跳记录,配一个「超过 N 小时没有心跳就报警」的哨兵。失败告警报的是「我出错了」,心跳哨兵报的是「我可能已经无法报错了」。
- 数据要回读。 这是后来另一次踩坑补上的:接口返回「写入成功」,数据却没进表(编码问题被平台静默丢弃)。所以关键写入之后,要把数据读回来核对一遍。接口的返回码只代表「它收到了请求」,不代表「它做了你以为的事」。
为什么新手(比如当时的我)都会栽在这
因为教程只教到「跑通」为止。跑通的那一刻,演示是成功的、心情是愉悦的、老板是满意的——没有任何信号提示你系统还缺一半。
那缺的一半叫运维意识:假设一切都会坏,然后确保坏的时候你是第一个知道的人。原型和生产系统的区别不在代码量,而在这个假设。
我现在评估任何自动化系统(包括别人做的),第一个问题不再是「能不能跑」,而是:
「它挂的时候,你怎么知道?」
答不上来,就还不算交付。