特来电混沌工程实践
一、導語
隨著大型分布式系統架構的演進和廣泛應用,軟件工程的最佳實踐也隨之改變。
我們通過分布式、服務化、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. 混沌實驗閉環
所有的混沌實驗必須實現閉環,發現問題,分析問題,解決問題
因此我們增加了一類單據統一管理混沌實驗,便于總結、分析、跟蹤
以上是我們今年搞混沌工程,提升系統可用性的一些實踐,分享給大家。
總結
- 上一篇: .NET 基金会完成第一次全面改选
- 下一篇: 构建现代Web应用时究竟是选择传统web