Netflix 混沌工程手冊 Part 3:實踐方法

weixin_33763244發表於2019-03-01

本文翻譯自 Netflix 工程師合著的 Chaos Engineering 一書。這本書介紹了混沌工程的主要概念,以及如何在組織中實踐這些概念和經驗。也許我們開發的相關工具只適用於 Netflix 自身的業務和系統環境,但我們相信工具背後的原則可以更廣泛地應用於其他領域。

InfoQ 將就這一專題持續出稿,感興趣的同學可以持續關注。

第一部分第二部分中,我們討論了混沌工程的初衷和背後的理論。然而將理論付諸實踐,是具有挑戰性的。任何系統都沒有現成的構建、排程,自動化實驗的工具,而且即使是最好的混沌工程框架,也需要良好適配才能發揮作用。

混沌工程起源於Netflix,但它的影響力已經從技術領域擴充套件到了其他行業。在一些會議上,我們經常聽到來自金融行業工程師們的一些保留意見。他們不願實施混沌工程實驗的原因是,害怕實驗會給客戶帶來資金或行業合規性的影響。然而我們堅持認為,該發生的故障,不會因為你的意願而不發生。即使實驗暴露風險點的同時會導致一些小的負面影響,提前瞭解和控制影響範圍,也比最終措手不及,應對大規模事故要好得多。現在我們已經看到很多銀行和金融公司在實踐混沌工程,為那些猶豫不決的企業提供了大量示例參考。

醫療行業的工程師們也表達了類似的疑慮。誠然,娛樂服務的中斷只會讓人覺得不方便,金融交易的失敗令人困惑並且可能導致大量損失,但醫療技術領域的任何失敗都可能會危及生命。然而我們還是想指出,激勵我們讓混沌工程規範化的許多科學原則正是起源於醫學。醫學研究的最高標準就是臨床試驗。我們絕不會忽視將混沌工程引入醫療領域的潛在影響,只是想說明,實際生活中已經存在很多具有同樣風險的先例,並且已經被廣泛接受了。

對混沌工程這樣一個新生的學科來說,付諸實踐是最有意義和最迫切的。瞭解關於如何實施、複雜性和實施時需要關注的問題,既可以幫助你找出目前在混沌工程之路上,你所處的位置,也可以指明組織中需要在何處發力來構建成功的混沌工程實踐。

8. 設計實驗

在討論完理論原則之後,我們來如何看看設計混沌工程實驗的細節。下面是大致的流程:

  1. 選定假設;

  2. 設定實驗的範圍;

  3. 識別出要監控的指標;

  4. 在組織內溝通到位;

  5. 執行實驗;

  6. 分析實驗結果;

  7. 擴大實驗範圍;

  8. 自動化實驗。

8.1 選定假設

你需要做的第一件事就是選定你要驗證的假設,我們在“多樣化現實世界事件”一節中有過討論。例如,你最近在訪問Redis時有超時報錯,於是想確保你的系統不會被這類快取訪問超時所影響。再比如,你希望驗證主從資料庫配置,在主資料庫故障時可以無縫切換到從資料庫。

不要忘記你的系統中一個重要的組成部分是維護它們的人。人工的行為對於降低事故率至關重要。例如有的公司採用如Slack或HipChat之類的即時通訊工具在故障時的進行溝通,當即時通訊工具不可用時,如何處理故障也有一套應急流程。那麼如何得知on-call工程師是否掌握了這個應急流程?執行混沌工程實驗就是很好的辦法。

8.2 設定實驗的範圍

當選定了要驗證的假設,下一步需要做的就是設定好實驗的範圍。這裡有兩個原則:“在生產環境執行實驗”和“最小化爆炸半徑”。實驗離生產環境越近,從實驗中獲得的收益就越大。雖然這麼說,但還是要仔細關注可能對系統和使用者造成影響的風險。

我們需要儘可能最小化實驗對使用者造成的影響,應該從一個小範圍的測試開始,然後一步步擴大,直到我們認為系統可以應對預期的最大影響。

因此,如“最小化爆炸半徑”一節中描述過的,我們提倡第一個實驗的範圍控制得越小越好。而且應該在生產環境中執行實驗之前,先在測試環境中試一試。一旦進入生產環境,一定要從最小量的使用者流量開始嘗試。例如,如果你要驗證系統在快取超時時會怎麼做,可以先用一個測試客戶端呼叫生產環境的服務,並且只針對這個客戶端引入快取超時。

8.3 識別出要監控的指標

明確了假設和範圍之後,我們需要選定用來評估實驗結果的指標,我們在“建立穩定狀態的假設”一節中討論過。要儘可能基於你的指標來驗證假設。例如假設是“主資料庫故障時,所有服務都正常”,那麼在執行實驗之前,你需要清晰定義什麼是“正常”。再舉個例子,如果你有一個明確的業務指標“每秒訂單數”,或者更低階別的指標,像響應時間和響應錯誤率,在執行實驗之前要明確定義清楚這些指標可以容忍的數值範圍。

如果實驗產生的影響比預期中的大,你就應該準備好立即終止實驗。可以預先設定好明確的閾值,例如,失敗請求佔比不超過5%。這可以幫助你快速決定在實驗進行中,要不要按下那個“大紅色按鈕”。

8.4 在組織內溝通到位

當你第一次在生產環境中執行混沌工程實驗時,你需要通知你所在組織中的其他成員,你將要做什麼,為什麼要做,以及什麼時間要做。

第一次執行的時候,你可能需要協調好每個需要參與的,對結果感興趣的,以及對生產影響有顧慮的團隊。隨著越來越多次的執行實驗,你和你的組織對系統的信心會越來越足,這時就沒必要每次都為了實驗傳送通知了。

關於混亂金剛的通知

我們第一次執行混亂金剛實驗,驗證AWS區域故障恢復實踐時,整個過程中與公司各團隊做了大量溝通,目的是讓每一個人都清楚我們將在什麼時間點讓某個區域失效。不可避免地會有很多例如功能釋出等的要求,讓我們推遲實驗。

隨著我們一次又一次越來越頻繁地進行實驗,混亂金剛逐漸被大家接受為一個“常規”事件。結果就是事先溝通越來越少。現在我們每三週執行一次,但已不需要發出通知了。在我們內部有一個可以訂閱的日曆,標明混亂金剛實驗在哪一天執行,但我們不會指明當天具體的執行時間。

8.5 執行實驗

截止目前準備工作都已完成,是時候執行實驗了!要盯住那些指標,因為你可能隨時需要終止實驗。隨時終止實驗的能力異常關鍵,因為我們是直接在生產環境執行實驗,隨時都可能對系統造成過度危害,進而影響外部使用者。例如一個電商網站,你一定要密切關注使用者是否能夠正常結算。要確保有足夠的報警機制,能實時獲知這些關鍵指標是不是掉到了閾值以下。

8.6 分析實驗結果

實驗結束後,拿當時的指標資料來驗證之前的假設是否成立。系統對於你注入的真實事件是否具備足夠的彈性?有沒有任何預期之外的事情發生?

多數混沌工程實驗暴露出來的問題,都會涉及多服務之間的互動,所以要確保把實驗結果反饋給所有相關的團隊,一同從整體的角度來消除隱患。

8.7 擴大實驗範圍

“最小化爆炸半徑”一節中描述的,當你從小範圍實驗中獲得了信心之後,就可以逐步擴大實驗範圍了。擴大實驗範圍的目的是進一步暴露小範圍實驗無法發現的一些問題。例如,微服務架構中一些小量的超時或許不會有什麼問題,但超過一定比例就可能會導致整體癱瘓。

8.8 自動化實驗

如“持續自動化執行實驗”一節中描述的,當你有信心手動執行混沌工程實驗之後,就可以開始週期性自動化執行實驗,持續從中獲得更大的價值。

9. 混沌工程成熟度模型

我們標準化混沌工程定義的一個目的是,在執行混沌工程專案時,我們有標準來判斷這個專案做得是好是壞,以及如何可以做得更好。混沌工程成熟度模型(CMM)給我們提供了一個評估當前混沌工程專案成熟度狀態的工具。把你當前專案的狀態放在這個圖上,就可以據此設定想要達到的目標,也可以對比其他專案的狀態。如果你想要提升這個專案的狀態,CMM的座標軸會給出明確的方向建議,你應該朝哪裡努力。

CMM的兩個座標軸分別是“熟練度”和“應用度”。缺乏熟練度時,實驗會比較危險、不可靠、且有可能是無效的。缺乏應用度時,所做的實驗就不會有什麼意義和影響。要在適當的時候變換在兩個不同維度的投入,因為在任何一個時期,要發揮混沌工程專案的最大效果需要在這兩個維度上保持一定的平衡。

9.1 熟練度

熟練度可以反映出,在你的組織中混沌工程專案的有效性和安全性。專案各自的特性會反映出不同程度的熟練度,有些完全不具備熟練度,而有些可能具備很高的熟練度。熟練度的級別也會因為混沌工程實驗的投入程度而有差異。我們對熟練度用入門、簡單、高階和熟練四個級別進行描述。

入門

  • 未在生產環境中執行實驗;
  • 全人工流程;
  • 實驗結果只反映系統指標,而不是業務指標;
  • 只對實驗物件注入一些簡單事件,如“關閉節點”。

簡單

  • 用複製的生產流量來執行實驗;
  • 自助式建立實驗,自動執行實驗,但需要手動監控和停止實驗;
  • 實驗結果反映聚合的業務指標;
  • 對實驗物件注入較高階的事件,如網路延遲;
  • 實驗結果是手動整理的;
  • 實驗是預先定義好的;
  • 有工具支援歷史實驗組和控制組之間的比較。

高階

  • 在生產環境中執行實驗;
  • 自動結果分析,自動終止實驗;
  • 實驗框架和持續釋出工具整合;
  • 在實驗組和控制組之間比較業務指標差異;
  • 對實驗組引入如服務級別的影響和組合式的故障事件;
  • 持續收集實驗結果;
  • 有工具支援互動式的比對實驗組和控制組。

熟練

  • 開發流程中的每個環節和任意環境都可以執行實驗;
  • 全自動的設計、執行和終止實驗;
  • 實驗框架和A/B測試以及其他測試工具整合以最小化影響;
  • 可以注入如對系統的不同使用模式、返回結果和狀態的更改等型別的事件;
  • 實驗具有動態可調整的範圍以找尋系統拐點;
  • 實驗結果可以用來預測收入損失;
  • 實驗結果分析可以用來做容量規劃;
  • 實驗結果可以區分出不同服務實際的關鍵程度。

9.2 應用度

應用度用來衡量混沌工程實驗覆蓋的廣度和深度。應用度越高,暴露的脆弱點就越多,你對系統的信心也就越足。類似熟練度,我們也對應用度定義了不同級別,分別是“暗中進行”,適當投入度,正式採用和成為文化。

“暗中進行”

  • 重要專案不採用;
  • 只覆蓋了少量系統;
  • 組織內部基本沒有感知;
  • 早期使用者偶爾進行混沌工程實驗。

適當投入度

  • 實驗獲得正式批准;
  • 工程師兼職進行混沌工程實驗;
  • 多個團隊有興趣並參與;
  • 少數重要服務也會不定期進行混沌工程實驗。

正式採用

  • 有專門的混沌工程團隊;
  • 所有故障的覆盤都會進入混沌工程框架來建立迴歸實驗;
  • 大多數關鍵服務都會定期進行混沌工程實驗;
  • 偶爾執行實驗性的故障覆盤驗證,例如“比賽日”的形式。

成為文化

  • 所有關鍵服務都高頻率進行混沌實驗;
  • 多數非關鍵服務高頻率進行混沌實驗;
  • 混沌工程實驗是工程師日常工作的一部分;
  • 所有系統元件預設要參與混沌工程實驗,不參與需要特殊說明。

9.3 繪製成熟度模型圖

繪製成熟度模型圖時,以熟練度作為Y軸,應用度作為X軸。會呈現出如下圖所示的四個象限。

\"\"

圖中我們拿混亂猴子,混亂金剛和混沌工程自動化平臺ChAP(帽子)作為示例。寫作本文時,我們的ChAP處在熟練度較高的位置,在之前的發展歷程中,我們努力的方向如圖中箭頭所示。現在根據這個圖,我們就知道我們需要專注在它的應用度上,以發揮出ChAP的最大潛力。

CMM幫助我們理解混沌工程專案處在什麼狀態,建議出我們應該聚焦在哪方面來持續提升,同時通過象限圖的方式給我們指出改進的方向。

10. 結論

我們相信,在任何開發和執行復雜分散式系統的組織機構裡,如果既想擁有高開發效率,又想保障系統具有足夠的彈性,那麼混沌工程一定是必備的方法。

混沌工程目前還是一個非常年輕的領域,相關的技術和工具也都剛剛開始逐步發展。我們熱切的期望各位讀者可以加入我們的社群,和我們一起不斷實踐、擴充混沌工程。

一些資源

我們建立了社群網站 http://chaos.community/ 和Google Group https://groups.google.com/forum/#!forum/chaos-community 。 期待你加入我們。

你也可以在Netflix的官方部落格 https://medium.com/netflix-techblog 找到更多關於混沌工程的資訊。當然,還有很多其他的組織在實踐混沌工程,例如:

  • Fault Injection in Production: Making the Case for Resiliency Testing
  • Inside Azure Search: Chaos Engineering
  • Organized Chaos With F#
  • Chaos Engineering 101
  • Meet Kripa Krishnan, Google’s Queen of Chaos
  • Facebook Turned Off Entire Data Center to Test Resiliency
  • On Designing And Deploying Internet-Scale Services

另外,還有很多為不同場景開發的開源工具:

Simoorg

​ Linkedin開發的故障注入工具。它非常易於擴充套件,並且很多關鍵元件都是可插拔的。

Pumba

​ 基於Docker的混沌工程測試工具以及網路模擬工具。

Chaos Lemur

​ 可以本地部署的隨機關閉BOSH虛擬機器的工具。

Chaos Lambda

​ 隨機關閉AWS ASG節點的工具。

Blockade

​ 基於Docker,可以測試網路故障和網路分割槽的工具。

Chaos-http-proxy

​ 可以向HTTP請求注入故障的代理伺服器。

Monkey-ops

​ Monkey-Ops用Go實現,可以再OpenShift V3.X上部署並且可以在其中生成混沌實驗。Monkey-Ops可以隨機停止OpenShift元件,如Pods或者DeploymentConfigs。

Chaos Dingo

​ Chaos Dingo目前支援在Azure相關服務上進行實驗。

Tugbot

​ Docker生產環境測試工具。

也有一些書籍講到關於混沌工程的一些主題:

Drift Into Failure by Sidney Dekker (2011)

Dekker的理論講的是,在一個組織內部,事故的發生都是因為各系統隨著時間慢慢滑向一個不安全的狀態,而不是某個單點突發的問題造成的。你可以把混沌工程想象成專門用來對抗這種滑動過程的方法。

To Engineer Is Human: The Role of Failure in Successful Design by Henry Petroski (1992)

Petroski描述了他們那裡的工程師是如何從過去的失敗中汲取教訓來進步的,而不是從過去的成功中找經驗。混沌工程正是一種既能發現系統中的問題點,又能避免大規模影響的方法論。

Searching for Safety by Aaron Wildavsky (1988)

Wildavksy的主張是,為了提高整體安全性,所有風險必須要被管理好。尤其是採用不斷試錯的方法,長期來說會比嘗試完全避免事故發生,要獲得更好的結果。混沌工程也是同樣的通過在生產環境進行實驗來擁抱風險,以期獲得系統更大的彈性的方法。

相關文章