永不闔眼的機器:一套 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 掉線。把已知的正常波動從告警裡擇出去,剩下的每一條才都值得你抬頭。 告警系統的敵人從來不是「漏報」一種,「狼來了」式的過報同樣會讓它失效。
八、收束:可靠性是一層層剝開的洋蔥
回頭看,這套系統裡沒有任何一顆「銀彈」。它之所以可靠,是因為一串樸素的東西疊在了一起:
職責分到三台設備 → 六層監控各看一種死法 → 六式冗餘各堵一個單點 → 頻率按代價分配 → 觸發用電平不用邊沿 → 告警分級去重再給人。
每一層單看都平平無奇,疊起來,才是「你敢三個月不看它」。
如果這篇只帶走一句話,我希望是這句:
業務邏輯決定它能不能工作;監控與冗餘,決定它能不能長期無人值守地工作。後者,才是「生產級」三個字的全部含義。