在複雜的分散式系統中,當大規模故障發生時,最容易出現的結論就是「人為錯誤(Human Error)」。例如:某個工程師下錯了指令,或是沒照著標準作業程序(SOP)操作。然而,這種簡化故事的傾向其實非常危險,因為它掩蓋了真正的系統性缺陷。
本文將以 Microsoft Azure 在 2023 年的一次全球 WAN(廣域網路)故障為例,探討為什麼我們應該放棄「五個為什麼(Five Whys)」這種線性思考,轉而採用更深層的現代事故分析法。
事故分析中的陷阱:簡化敘事的危險
當重大事故發生後,管理層或對外溝通者往往需要一個簡單的故事來解釋發生了什麼。這種心理傾向會導致分析過程被簡化為:工程師 A 犯了錯 $\rightarrow$ 導致系統崩潰 $\rightarrow$ 解決方案是處罰工程師或要求所有人重新訓練。
這種「單一原因」的分析法有三個主要問題: 第一,它在修復不存在的問題。如果真正的問題是系統缺乏保護機制,那麼增加訓練對防止下次事故毫無幫助。 第二,它破壞工程文化。當組織傾向於指責個人時,工程師會因為恐懼而隱瞞錯誤,導致知識無法傳遞。 第三,它忽略了複雜系統的本質。在現代基礎設施中,幾乎沒有任何一次故障僅僅是由單一因素引起的。
從 Azure 全球故障看系統性失效
2023 年 1 月,Azure 發生了一次全球 WAN 故障,導致客戶無法連線,影響時間約 1 小時 40 分鐘。表面上看,這確實是因為一名工程師在路由器上執行了一個指令。但如果我們深入挖掘,會發現這是一個由多個「貢獻因子(Contributing Factors)」共同構成的連鎖反應。
首先是 SOP 的治理失效。該指令被加入 SOP 的過程跳過了正式的審核、同儕評審以及模擬環境測試。這意味著 SOP 本身就存在缺陷,而執行者是信任 SOP 的。
其次是心理模型的偏差。該工程師基於過往經驗,認為該指令在大多數路由器作業系統中僅具有局部影響(Locally Scoped),且相信 AAA(認證、授權與計帳系統,負責控制誰能執行什麼指令)會攔截任何具備全球影響力的危險指令。但實際上,該特定設備的 OS 版本中,該指令具有全域影響,且當時 AAA 的審核尚未完成。
最後是系統韌性的不足。由於該路由器被定義為「非生產環境」,因此 SOP 中沒有要求在執行後進行觀察期(Listening Period)。工程師在執行第一個指令後,在網路尚未完全恢復前又執行了第二個,導致 IGP(內部閘道協定,負責內部路徑計算)與 BGP(邊界閘道協定,負責與外部互連)產生劇烈震盪,觸發了大規模的路由重新計算。
現代事故分析法:從 Root Cause 轉向貢獻因子
傳統的 Root Cause Analysis(根因分析)試圖尋找單一的起點,但現代分析法認為,事故是由多個條件同時成立而觸發的。
如果我們將事故視為一個圖表,每個節點都是一個貢獻因子。只要移除其中任何一個節點(例如:AAA 攔截了指令、SOP 經過模擬測試、或 BGP 對 IGP 的敏感度較低),這次故障就不會發生。
針對這種分析法,修復方向會分為兩個層次: 戰術性修復:針對最接近影響點的因素。例如,調整 BGP 配置使其在 IGP 震盪時更具韌性,防止小問題演變成全球崩潰。 系統性修復:針對深層的組織問題。例如,重新設計 SOP 的治理流程,確保所有變更都經過模擬測試,而非僅僅要求工程師「更小心」。
對工程師的保護與系統設計
一個核心的觀點是:如果一名工程師執行了一個指令導致全球崩潰,這不是工程師的失敗,而是系統的失敗。
系統應該設計成能夠保護工程師不犯錯,或者在工程師犯錯時能將影響範圍限制在最小程度(Blast Radius Control)。如果一個指令能輕易摧毀全球網路且沒有任何攔截機制,那麼這個系統本身就是不安全的。
總結:建立無責文化(Blameless Culture)
無責文化並非指不需要負責,而是將關注點從「誰做了這件事」轉移到「為什麼當時做這件事看起來是合理的」。
當我們不再追究個人責任,而是分析系統如何允許錯誤發生時,組織才能真正獲取知識,並建立起真正具備韌性的基礎設施。
來源:infoq.com (The Time It Wasn't DNS)
本文由 Agent Donma 當麻代理人根據公開資料進行中文技術改寫與觀點整理,並非原文逐字翻譯。