永不合眼的机器:一套 7×24 生产级自动化系统的监控与冗余解剖
一、真正的工程,在故障路径
一个只跑「顺境」的脚本和一个生产级系统,代码看起来可能八九不离十。区别藏在你看不见的地方:
- 顺境脚本假设网络永远通、接口永远按时返回、机器永远醒着、自己永远不崩。
- 生产级系统假设上面每一条迟早都会破,并且为每一种破法预留了退路。
有一条经验法则值得先记住:在一个真正 7×24 的系统里,业务逻辑往往只占三成代码,剩下七成是「监控它有没有在好好干活」和「某个环节挂了怎么办」。 本文剩下的篇幅,就是拆这七成。
样本系统由四个部分组成:一台企业级路由器(网络关口)、一台云端 VPS(前线执行)、一台本地 Mac 控制中枢(感知与决策),外加一个跑在 VPS 上、需要秒级响应外部事件的链上资产监控与自动响应系统。体量精悍,五脏俱全——生产级系统该有的坑,它一个没少踩。
二、三台设备,各司其职
第一层可靠性,不在代码里,在架构里:没有任何一台机器同时既是大脑又是手脚。

| 设备 | 角色 | 跑什么 | 为什么放这 |
|---|---|---|---|
| 企业级路由器 | 网络关口 · 链路命脉 | 链路健康、代理、DHCP、高吞吐转发 | 所有内网流量的必经关口,它决定前两者能不能互相说上话 |
| 本地 Mac 控制中枢 | 感知 · 决策 · 人机接口 | 全局扫描、定时巡查、告警汇聚推送 | 人要看、要决策、要汇总的东西放这——它允许关机 |
| 云端 VPS | 前线 · 7×24 业务执行 | 常驻服务、链上监控、自动执行、看门狗 | 凡是「必须一刻不断」的业务,只能放在永远醒着的云端 |
一句话抓住要害:控制中枢可以睡觉,前线执行不能。 所以职责这样切——「必须 7×24」的放 VPS,「人要参与」的放本地,「网络命脉」的是路由器。三者分离本身就是冗余:本地 Mac 合盖睡了,VPS 上的业务照跑不误;这在「大脑手脚合一」的单机方案里是做不到的。
三、同心圆:谁在看着谁
这是全篇最重要的一张图。
新手最常见的误解,是以为「加了监控」= 「装了个报警」。真相是:监控是分层的,而且——
每一层,只能看见它内层看不见的那一类故障。
把它想象成一颗洋葱,从最里的业务逻辑,一层层包到最外的「人的注意力」:

| 层 | 它盯什么 | 机制 | 它看不见什么(交给上一层) |
|---|---|---|---|
| ① 业务逻辑 | 探测→判断→执行 | 脚本主循环 | 不知道自己「死没死」 |
| ② 进程存活 | 进程有没有退出 | systemd Restart=always | 进程「活着,却卡死不干活」 |
| ③ 进程健康 | 活着的进程在不在真干活 | 看门狗 WATCHDOG=1 / 超 7min 重启 | 整台机器断电、断网、宕机 |
| ④ 节点存活 | 整台远端机在不在线 | 控制中枢定时 SSH 探测 | 发现了,谁来通知人 |
| ⑤ 感知汇聚 | 所有异常汇总 | 快照 + 每小时推送 | 还需真正送达到人 |
| ⑥ 人的注意力 | 人最终知不知道 | 一条推送落到手机 | ——链条终点 |
逐层看下去,你会发现每一层都有一个它自己填不上的洞,恰好是上一层存在的理由:
- 第②层的盲区,催生了第③层。 进程崩溃退出,
Restart=always秒级拉起——但如果进程没崩、还在,却卡死在某个调用上不动了呢?第②层的判据是「进程在不在」,它看不见「在,但没干活」。 - 补这个洞的,是看门狗:进程每干完一轮活,主动向系统喊一声「我还活着」;超过设定时限(这里是 7 分钟)没喊,系统就判定它假死,强制重启。这一层专治「活着但没在干活」。
- 但第③层自己也有盲区:如果整台 VPS 断电、断网、宕机,看门狗跟着一起没了,它报不了警。于是要有第④层——本地控制中枢从另一台机器上定时探测每个远端节点,机器整个失联时,在这一层才被发现。
这条链的价值,恰恰在于分工看不同的死法。任何一层都无法独自覆盖全部故障;把它们叠起来,才织成一张没有明显破洞的网。
四、频率的经济学:漏检代价定节奏
既然要监控,多久看一次?统一每秒一次?太贵,而且没必要。正确答案是一条朴素的经济学:
巡查频率,与「漏检一次的代价」成正比。

| 频率 | 监控对象 | 漏检一次的代价 |
|---|---|---|
| 3 秒 | 核心状态探测(外部事件翻转) | 资产全损——每一秒都值钱 |
| 60 秒 | 资源动向(余额 / 资源流动) | 重要但不致命,分钟级足够 |
| 7 分钟 | 进程健康看门狗 | 假死无人知;但「卡死」本身罕见,不必更密 |
| 1 小时 | 感知汇聚推送 | 故障晚一小时发现,通常还能救 |
| 24 小时 | 存活心跳 | 纯兜底,只为证明「我还在」 |
一个反直觉、却极重要的推论:不是所有东西都值得高频监控。 把「git 仓库有没有及时提交」也拿去每秒轮询,除了烧资源,只会让真正要紧的告警淹没在噪音里。
频率错配——该快的慢了、该慢的快了——是新手监控系统最常见的病。核心事件用小时级轮询,会错过救命窗口;无关紧要的状态用秒级刷屏,会训练出「狼来了」的麻木。把每一项监控的频率,对齐它「漏一次赔多少」,这套系统的巡查节奏就自然分层了。
五、冗余六式:单点失效不致命
监控负责发现问题,冗余负责问题发生时不塌。这套系统里的冗余,可以干净地归成六类——关键是,每一类各堵一个不同的单点。

| 式 | 做法 | 它拔掉的单点 |
|---|---|---|
| ① 通道冗余 | 报警同时走两条 Telegram 通道(一个群 + 一个私聊) | 单条通道失联 |
| ② 数据源冗余 | 外部状态从两个独立节点查,动作也向多个节点同时发 | 单节点故障或「说谎」 |
| ③ 判定冗余 | 不轻信中间信号;以权威结果为准,遇歧义一律判「未知」 | 谎报成功 |
| ④ 自愈冗余 | 崩了自动重启,卡死了看门狗踢一脚重启 | 进程假死 |
| ⑤ 存活冗余 | 分层心跳 + 跨设备探测,总有一层能证明整体还活着 | 整体失联 |
| ⑥ 时间冗余 | 失败不等于放弃,条件仍成立就下一轮再试 | 偶发的单次失败 |
其中两式值得展开,因为它们是新手最容易做错的地方:
③ 判定冗余——不要轻信中间信号。 一个动作「已经发出去了」不等于「成功了」。正确的做法是回查权威的最终结果来确认,而不是看「发出去有没有被接受」。同样,当一次状态查询返回了模棱两可的东西(半截数据、错误码、空响应),绝不能替它猜一个方向——一律当「未知」,宁可下一轮重查,也不拿一个猜测去触发不可逆的动作。 这一条,是从一次「把失败的操作误报成成功」的真实事故里换来的。
⑥ 时间冗余——失败只是「这轮没成」。 它直接引出下一节,也是整套系统里最贵的一课。
评估任何一个冗余,其实只要问一句话:它拔掉的是哪一个单点? 答得上来,它就值得存在;答不上来,那它多半只是让你「感觉更安全」的过度设计。
六、边沿与电平:一字之差,生死之别
这是整套系统里最贵的一课,值得单独讲。
早期版本用的是边沿触发(edge-triggered):只在「状态发生翻转的那一瞬间」动作。逻辑上很自然——条件满足的瞬间,冲。
问题在于:如果那一下没成功呢? 网络抖动、资源不足、节点返回半截数据……只要那一次失败,而「翻转的瞬间」已经过去、永远不会再来第二次,系统就永久缴械了。后面就算条件真的一直满足、真的可以执行,它也不动了——更糟的是,它还自以为一切正常。
改造后换成电平触发(level-triggered):不看「翻转的瞬间」,只看「当前条件是否成立」。只要「可执行 ∧ 尚未成功」,每一轮都重新尝试;失败了,下一轮接着来,直到确认真正干成,才收手。

这个差别听起来抽象,代价却极具体:
| 边沿触发(v1) | 电平触发(v2) | |
|---|---|---|
| 一次失败的后果 | 满盘皆输,且无声无息 | 只是「这轮没成」,下轮自动重试 |
| 自愈能力 | 无——错过瞬间就永久失效 | 有——条件仍成立就一直试 |
| 失败可见性 | 假装无事,最危险 | 每轮留痕,可观测 |
配套的看门狗,其实是同一种哲学的另一个应用。看门狗不去「侦测某个具体故障」——它反过来,要求进程持续证明自己在工作:每干完一轮就喊一声「我还活着」,喊不出来就重启。
与其枚举所有可能的死法,不如要求程序持续拿出「活证」。 你永远列不全一个系统会怎么死;但你可以要求它「不能自证在工作,就重启」。这是从「穷举故障」到「要求活证」的思路翻转,也是看门狗真正的威力所在。
七、告警的哲学:宁可吵醒,不可失明
监控与冗余的尽头,是一条落到人手机上的消息。这最后一环也有讲究,几条实战原则:
| 原则 | 说明 |
|---|---|
| 分级 | 致命的(资产 / 整机)才 Critical,值得半夜吵醒你;日常的(某仓库久未提交)降为 Warning,汇总即可 |
| 去重 + 冷却 | 同一条「油量不足」每小时最多报一次;否则刷屏,等于没报 |
| 已知无害要静音 | 笔记本带出门、内网探测不到路由器,是正常的「离家即离线」,不该告警——否则天天狼来了,真狼来了你已麻木 |
| 报警要能自证 | 进程重启后主动发一条「我起来了」,让你知道它刚经历过一次自愈,而不是默默重启、假装无事 |
其中「已知无害要静音」最考验分寸。这套系统的感知引擎里,就特意让「远端节点离线告警」跳过那台企业级路由器——因为它探测不到,最常见的原因是本地设备被带出了门(不在同一内网),属于已知正常态;真正需要吵醒人的,是那台本该 7×24 在线的 VPS 掉线。把已知的正常波动从告警里择出去,剩下的每一条才都值得你抬头。 告警系统的敌人从来不是「漏报」一种,「狼来了」式的过报同样会让它失效。
八、收束:可靠性是一层层剥开的洋葱
回头看,这套系统里没有任何一颗「银弹」。它之所以可靠,是因为一串朴素的东西叠在了一起:
职责分到三台设备 → 六层监控各看一种死法 → 六式冗余各堵一个单点 → 频率按代价分配 → 触发用电平不用边沿 → 告警分级去重再给人。
每一层单看都平平无奇,叠起来,才是「你敢三个月不看它」。
如果这篇只带走一句话,我希望是这句:
业务逻辑决定它能不能工作;监控与冗余,决定它能不能长期无人值守地工作。后者,才是「生产级」三个字的全部含义。