為什麼學習必須融入日常工作#

在複雜系統中工作時,我們不可能預測每個行動的所有結果。即使使用了靜態的預防工具(如 checklist 和 runbook),意外和災難性事故仍然會發生。

為了在複雜系統中安全地工作,組織必須不斷精進自我診斷自我改善的能力——善於偵測問題、解決問題,並將解決方案散播到整個組織。這會創造一個動態的學習系統,讓我們能理解錯誤並將理解轉化為防止未來重蹈覆轍的行動。

Dr. Steven Spear 將這樣的組織描述為韌性組織(resilient organizations)——「善於偵測問題、解決問題,並將效果擴展到整個組織」。這類組織能自我修復:「對這樣的組織來說,回應危機不是特殊工作,而是持續進行的事情。正是這種回應能力,成為它們可靠性的來源。」

Netflix 與 AWS 大當機的案例#

2011 年 4 月 21 日,整個 Amazon AWS US-EAST 可用區域當機,幾乎所有依賴它的客戶都受到影響(包括 Reddit 和 Quora)。然而 Netflix 卻幾乎毫髮無傷

原因在於 Netflix 從 2009 年開始將單體式 J2EE 應用重新架構為 cloud native 設計:

  • 系統設計為鬆耦合(loosely-coupled),每個元件都有積極的 timeout 設定
  • 每個功能和元件都設計為優雅降級(graceful degradation)——例如流量高峰時顯示靜態內容而非個人化推薦
  • 他們還建造了 Chaos Monkey,持續隨機關閉生產環境伺服器,以確保服務能自動恢復

Netflix 團隊運行 Chaos Monkey 是為了獲得保證——確認他們已達成營運韌性目標,透過持續向預生產和生產環境注入故障來驗證。

當 Chaos Monkey 第一次在生產環境運行時,服務以團隊從未預見的方式失敗。但透過在正常工作時間不斷發現和修復這些問題,Netflix 工程師快速地、迭代地打造出更具韌性的服務。

建立公正的學習文化#

學習文化的先決條件之一是:當事故發生時,組織的回應被視為「公正的」(just)。Dr. Sidney Dekker 創造了 just culture 一詞,他寫道:「當對事件和事故的回應被視為不公正時,會阻礙安全調查、在從事安全關鍵工作的人身上製造恐懼而非警覺,使組織更官僚而非更謹慎。」

拒絕「壞蘋果理論」#

Dr. Dekker 將透過淘汰犯錯者來消除錯誤的想法稱為 Bad Apple Theory。他主張這是無效的,因為「人為錯誤不是問題的根源;人為錯誤是我們提供的工具設計所造成的結果。」

如果事故不是由「壞蘋果」引起,而是我們所創造的複雜系統中不可避免的設計問題,那麼我們的目標應該永遠是:

  • 最大化組織學習的機會
  • 持續強化那些能暴露和更廣泛分享日常工作問題的行動
  • 將錯誤、失誤、疏忽以學習的視角來看待

當工程師犯錯並感到安全可以提供詳細資訊時,他們不僅願意被追究責任,還會熱心地幫助公司其他人避免相同的錯誤。反之,如果我們懲罰犯錯的工程師,所有人都會失去提供必要細節的動機,保證失敗會再次發生。

安排無責備事後檢討會議#

當事故和重大事件發生時(例如部署失敗、影響客戶的生產問題),我們應在事件解決後進行 blameless post-mortem。這個由 John Allspaw 創造的術語,幫助我們以聚焦於失敗的情境面向及當事人決策過程的方式來檢視錯誤。

無責備事後檢討的執行要點#

在會議中,我們應該:

  • 建構時間線,從多個角度收集失敗的細節,確保不懲罰犯錯的人
  • 賦權所有工程師改善安全,讓他們能詳細描述自己對失敗的貢獻
  • 鼓勵犯錯的人成為專家,教育組織其他人如何避免未來犯同樣的錯
  • 接受人類總有裁量空間,而對這些決定的判斷來自事後諸葛
  • 提出對策以防止類似事故再次發生,確保對策有目標日期和負責人

應出席的利害關係人#

  • 參與可能導致問題的決策的人
  • 發現問題的人
  • 回應問題的人
  • 診斷問題的人
  • 受問題影響的人
  • 以及任何有興趣參加的人

在會議中應明確禁止使用「本來應該」或「本來可以」這類反事實陳述(counterfactual statements),因為它們用「想像中的系統」來框架問題,而非用「實際存在的系統」。正確的問題是:「當我採取那個行動時,為什麼它在當下是合理的?」

對策的設計#

Dan Milstein(Hubspot 首席工程師之一)在每次無責備事後檢討會議開始時都會說:「我們正在為一個我們跟今天一樣笨的未來做準備。」換言之,對策不能僅僅是「更小心」或「少犯蠢」——必須設計真正的對策,例如:

  • 在部署管線中加入新的自動化測試來偵測危險狀況
  • 增加更多生產環境遙測
  • 識別需要額外同行審查的變更類別
  • 進行定期的 Game Day 演練

廣泛發布事後檢討報告#

完成無責備事後檢討會議後,應廣泛宣布會議記錄和相關文件(時間線、IRC 聊天記錄、外部通訊等),並放置在集中位置讓整個組織都能存取和學習。

Randy Shoup(前 Google App Engine 工程總監)描述事後檢討文件的價值:「在 Google,一切都是可搜尋的。所有事後檢討文件都放在其他 Googler 看得到的地方。當任何團隊遇到聽起來類似過去某件事的事件時,這些事後檢討文件是最先被閱讀和研究的。」

Etsy 為了管理大量的事後檢討記錄,開發了一個名為 Morgue 的工具,能輕鬆記錄每個事故的各種面向(如 MTTR 和嚴重程度),並支援 Markdown 格式、嵌入圖片、標籤和歷史紀錄。使用 Morgue 後,記錄的事後檢討數量顯著增加。

降低事件容忍度以發現更微弱的失敗信號#

隨著組織學會如何有效地發現和解決問題,它們需要降低「什麼構成問題」的門檻,以持續學習。例如,Alcoa 在將工安事故降到罕見後,CEO Paul O’Neill 開始要求通報事故未遂事件(near-misses)。

NASA Columbia 號的教訓#

2003 年 Columbia 太空梭在重返大氣層時爆炸。事前已有中階 NASA 工程師報告了隔熱泡棉脫落的問題,但他們的聲音被忽視。Roberto、Bohmer 和 Edmondson 在 Harvard Business Review 中分析了 NASA 文化如何助長這個問題——他們區分了兩種組織模式:

  • 標準化模型:常規和系統治理一切,嚴格遵循時程和預算
  • 實驗模型:每天每個活動和每條新資訊都被評估和辯論,類似研發實驗室

「光靠警覺不能防止模糊威脅(微弱失敗信號)變成代價高昂的(有時是悲劇性的)失敗。」——重要的是文化和心態,而不僅僅是「小心」。

重新定義失敗,鼓勵承擔風險#

組織領導者透過行動強化組織文化和價值觀。Netflix 的 Roy Rapoport 觀察到:「高績效 DevOps 組織會更頻繁地失敗和犯錯。這不僅是可以的,更是組織所需要的。如果高績效者的部署頻率是三十倍但變更失敗率只有一半,他們顯然有更多失敗。」

他分享了一個故事:一位工程師在十八個月內兩次導致 Netflix 大規模當機。「但這是一個我們絕對不會解雇的人。在同樣的十八個月裡,這位工程師將我們的營運和自動化水準提升了好幾個量級。」

注入生產環境故障以提升韌性與學習#

注入故障到生產環境(如 Chaos Monkey)是提升韌性的方法之一。我們透過定期(甚至持續地)執行測試,確保系統能以特定且可控的方式失敗。

Michael Nygard(Release It! 作者)評論:「就像在汽車中建造潰縮區以吸收撞擊力並保護乘客安全一樣,你可以決定系統的哪些功能是不可或缺的,並建造失敗模式來保護這些功能。如果你不設計你的失敗模式,你將得到無法預測的——而且通常是危險的——結果。」

Netflix 的韌性實證#

2014 年「Great Amazon Reboot」期間,近 10% 的 Amazon EC2 伺服器需要重啟。Netflix 的 2,700 多個 Cassandra 節點中有 218 個被重啟,22 個未能成功重啟。結果:Netflix 該週末經歷了零停機時間

舉辦 Game Day 演練失敗場景#

Game Day 是由 Jesse Robbins 所推廣的災難恢復演練概念,源自韌性工程(resilience engineering)的學科。Robbins 將韌性工程定義為「透過對關鍵系統進行大規模故障注入來提升韌性的演練」。

Game Day 的執行方式#

  1. 安排一個災難性事件(如模擬整個資料中心毀壞)在未來某個時間點發生
  2. 給團隊時間準備——消除所有單點故障,建立必要的監控和容錯程序
  3. Game Day 團隊定義並執行演練(如資料庫容錯切換、關閉重要網路連線)
  4. 發現的任何問題都被識別、處理並再次測試
  5. 在預定時間執行停機——讓系統自然失敗,讓人員依循他們的流程

Google 的 Disaster Recovery Program(DiRT) 是模擬災難的絕佳範例。他們模擬過矽谷地震(導致整個 Mountain View 園區與 Google 斷開連線)、主要資料中心完全斷電,甚至外星人攻擊工程師所在的城市。

Figure 42: Size of change vs. lead time for reviews at Google