歡迎光臨
每天分享高質量文章

特來電混沌工程實踐

一、導語

隨著大型分散式系統架構的演進和廣泛應用,軟體工程的最佳實踐也隨之改變。
我們透過分散式、服務化、DevOps、敏捷開發,快速響應業務的需求變化,支援大規模分散式應用。但這些做法帶來效益的同時,也帶來了另一個緊迫問題:我們到底有多少把握來確保線上複雜的系統能夠正常工作呢?
即便是分散式系統中每個獨立的服務都正常工作,服務之間的相互呼叫也仍然可能造成不可預期的結果。這些結果在現實中可能很少發生,但是一旦發生就會影響整個生產環境,使得整個分散式系統變得混亂不堪,甚至出現服務雪崩、系統全面宕機。

不是由你來選擇那一刻,而是那一刻來選擇你!
你只能選擇為之做好準備。
           —消防隊長 Mike Burtch

因此,我們有必要線上上事故出現之前,提前識別出系統的有哪些點、這些弱點的影響範圍。我們需要一種方式來管控這些系統的固有混沌,在保證快速響應業務需求變化的同時,做到最後不管系統有多複雜,我們的線上應用經得住各種“”。

透過應用一些經驗探索的原則,來觀察系統是如何反應的。這就跟科學家做實驗去學習物理定律一樣,透過做實驗去瞭解整個系統。我們從受控的試驗中掌握分散式系統執行行為的過程,稱為混沌工程。

混沌工程不是製造問題,而是揭示問題。
              —Nora Jones,Netflix 高階混沌工程師

混沌工程的典型實踐-Chaos Monkey,搗亂的猴子;拜 Netflix 所賜,現在大部分的混沌工程專案都叫做 Monkey,也就是一隻搗亂的猴子,在你的系統裡面上蹦下竄,不停搗亂,直到搞掛你的系統。

為什麼需要混沌工程:

應用混沌工程可以提升整個系統的彈性。透過設計並且進行混沌實驗,我們可以瞭解到系統脆弱的一面,在還沒出現線上事故之前,我們就能主動發現這些問題,並盡可能的解決這些問題。

混沌工程和測試有什麼區別:

雖然混沌工程跟傳統測試通常都會共用很多測試工具的,譬如都會使用錯誤註入工具,但:
混沌工程是透過實踐對系統有更新的認知,而傳統測試則是使用特定方式對某一塊進行特定測試。
譬如在傳統測試裡面,我們可以寫一個斷言,我們給定特定的條件,產生一個特定的輸出,如果不滿足斷言條件,測試就出錯了,這個其實是具有很明確的特性。但混沌工程是試驗,而試驗會有怎樣的結果,我們是不確定的。
譬如我們可以進行下麵的這些試驗:

  • 模擬整個 IDC 宕機
  • 選擇一部分網路連連線註入特定時間的延遲
  • 隨機讓一些函式丟擲
  • 異常強制 NTP 時間不同步
  • 生成 IO 錯誤
  • 榨乾 CPU

這些混沌試驗到底會有什麼樣的結果,有些我們可以預料,但有些可能我們就不會預先知道,只有發生了,才會驚訝,
“啊,怎麼會這樣!”

二、混沌工程的方法論

既然是工程,那麼就會有方法論,也就能詳細的歸納總結出來實施的步驟
1. 混沌工程的一般實施步驟

  • 尋找一些系統正常執行狀態下的可度量指標,作為基準的“穩定狀態”
  • 假設實驗組和對照組都能繼續保持這個“穩定狀態”
  • 對實驗組進行事件註入,如伺服器崩潰、硬碟故障、網路連線斷開等等
  • 比較實驗組和對照組“穩定狀態”的差異,推翻上述第2條的假設

如果混沌實驗前後保持的“穩定狀態”一致,則可以認為系統應對這種故障是彈性的,從而對系統建立更多信心。相反的,如果兩者的穩定狀態不一致,那我們就找到了一個系統弱點,從而可以修複它,提高系統可靠性。

2. 實施混沌工程的推薦原則
2.1. 根據“穩定狀態下系統的特徵”做一個假設
以充電為例,充電服務可能包含了訂單服務,開啟充電、結束充電、電量更新服務,賬戶服務、計費策略服務,“假設”不是著眼於各個“螺絲釘”服務的具體狀態,而是著眼於整個充電系統正常運作下的外部表現(狀態),如開啟充電TPS、正在充電中訂單數、電量更新 TPS、結束充電TPS、充電服務異常等等,這些監控指標曲線一般不會大起大落,其變化趨勢是可以預期的。
但是有一點需要特別註意,某些問題雖然不會怎麼影響整體監控指標,
但是仍然需要監控系統中各個節點的微觀指標(如CPU、IO等)。

 2.2 事件是現實世界真的可能發生的
任何可能影響系統穩定狀態的都可以作為事件,常見的,如
故障類:像伺服器宕機、重啟、斷網等硬體故障、服務超時、Nginx不可用、核心應用未重啟等應用故障;
非故障事件:像流量激增
同時,還可以分析曾經引起系統故障的事件的種類和頻次,針對性的排列優先順序,並復現這些事件,避免系統再次出現這種故障。

 2.3. 在生產環境跑
根據第1條,一般只有生產環境的指標是可預測的,如每日充電訂單量、開啟充電量、電量更新TPS等。而且,由於測試環境和生產環境不可能一模一樣,為了真實反映系統的可靠性,一般推薦在生產環境實施混沌工程。

 2.4. 持續整合
線上應用每天都在更新,所以像跑持續整合一樣實施混沌工程,持續發現問題、解決問題。

 2.5. 最小化影響範圍
混沌工程可能導致線上功能不可用,甚至造成宕機事故,所以在以找出系統弱點為目的的前提下,需要最小化故障影響範圍,並且當出現嚴重問題時可以迅速恢復,即故障是可控的。鑒於此,需要控制最小化影響範圍。

上面是最理想情況下的混沌工程,現實中我們需要根據現有軟體成熟度有階段的實施混沌:

階段一:分散式系統彈性化一般
以京東為例,他們會在雙十一大促之前進行故障演練,將團隊分為兩組,一組作為故障的製造者,另外一組作為故障的解決者和響應者,來考察故障發生的時候,團隊對故障的檢測、響應、處理還有恢復能力。達到小的故障不需要人介入,大故障人工介入可以快速處理的目的。透過在大促之前的兩個月期間密集的開展混沌工程,提高團隊對大規模故障的容錯能力。

階段二:分散式系統彈性化成熟
以Netflix為例,他們基本上已經在按照上述理想的步驟和原則實施混沌工程,工作日持續、自動的實施混沌工程,系統具備高度的可靠性,彈性伸縮。

三、混沌工程的成熟度模型

混沌工程成熟度模型,Netflix (網飛)總結了兩個維度,一個是複雜度,一個就是接受度
前者表示的是混沌工程能有多複雜,而後者則表示的是混沌工程被團隊的接受程度。
複雜度分為哪幾個階段:

接受度分為哪幾個階段:

我們目前處於起步發展階段,線上生產環境實施混沌工程,風險很大,也不可控,因此:

我們在壓測模擬環境實施混沌工程,搭建類似生產的小型模擬環境,以正常、合理的測試結果,作為基準“穩定狀態”。在模擬測試的過程中,對系統實施各類混沌實驗後,透過觀察測試結果來評估系統的可靠性,從而尋找系統弱點,
登記Bug,進行修複。

同時,透過自動化運維平臺,實現混沌實驗異常註入和持續執行。

四、混沌工程的執行

1. 混沌工程的整體實施流程

2. 混沌事件註入

應用層的混沌事件

中介軟體層混沌事件

資料庫層和基礎實施層混沌事件

3. 混沌實驗閉環

所有的混沌實驗必須實現閉環,發現問題,分析問題,解決問題

因此我們增加了一類單據統一管理混沌實驗,便於總結、分析、跟蹤

以上是我們今年搞混沌工程,提升系統可用性的一些實踐,分享給大家。

贊(0)

分享創造快樂