混沌工程 - 軟體系統高可用、彈性化的必由之路

有贊技術發表於2018-06-25

隨著摩爾定律的終結,單機計算效能已達到了極限,然而,我們的軟體系統不論是規模還是複雜度一直在增長,所以軟體系統都不約而同的朝著分散式化方向發展。近年來,隨著雲服務、容器的出現,某些分散式系統也更容易微服務化。拋開這些形形色色的分散式技術,我們對系統可靠性的述求卻是一致的:分散式系統需要高可用,即使出現了單點或叢集故障,也希望系統具備自我恢復或優雅降級的彈效能力、容錯能力。我們在合理的架構,高質量的程式碼,完善的測試等等方面做了很多努力,然而很多分散式系統仍舊達不到高可用、彈性化,為了儘可能發掘系統中存在的弱點,很多大型軟體公司都引入了混沌工程,如國外的谷歌、網飛,國內的京東等等。哪些可以稱之為系統弱點呢,比如

  • 外部系統故障,導致內部系統連鎖故障,我司即出現過因為七牛服務故障導致的內部故障
  • 服務不可用時,不合適的降級方案
  • 不合適的超時機制,導致請求錯誤時無限次重試

混沌工程的定義:

通過觀察分散式系統在受控的故障注入測試中的行為變化發掘系統弱點,並針對性的改進,從而提高系統可靠性,建立系統抵禦失控條件的能力的信心。所以,混沌工程並不是一個新概念,常見的異地容災測試也是混沌工程的一種應用。

混沌工程的一般實施步驟

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

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

混沌工程的理想原則:

1)根據“穩定狀態下系統的特徵”做一個假設

以電商下單為例,下單系統可能包含了商品服務,交易服務,支付服務,“假設”不是著眼於各個“螺絲釘”服務的具體狀態,而是著眼於整個下單系統正常運作下的外部狀態,如下單量、成交金額、系統吞吐量、延時、錯誤率等等,這些指標一般會有大盤監控,而且除非遇到促銷活動,這些指標曲線一般不會大起大落,其變化趨勢是可以預期的。但是有一點需要特別注意,某些問題雖然不會怎麼影響大盤資料(如快取失效、一個CDN節點失效等等),但是我們仍舊需要監控系統中各個節點的微觀指標(如CPU、IO等)以期發現這類問題(快取失效可能導致Mysql叢集壓力增大,CPU/IO等壓力變大)。

2)事件是現實世界真的可能發生的

任何可能影響系統穩定狀態的都可以作為事件,常見的,如

  • 故障類:像伺服器當機、斷網等硬體故障,像七牛等外部服務不可用的軟體故障
  • 非故障事件:像流量激增

我們還可以分析曾經引起系統故障的事件的種類和頻次,針對性的排列優先順序,並實施這些事件,避免系統再次出現這種故障。

3)在生產環境跑

根據第1條,一般只有生產環境的指標是可預測的,如新使用者日註冊量,使用者日下單量。而且,由於測試環境和生產環境不可能一模一樣,為了真實反映系統的可靠性,一般推薦在生產環境實施混沌工程。

4)持續整合

網際網路軟體每天都在更新,所以像跑持續整合一樣實施混沌工程具有現實意義。

5)最小化影響範圍

根據第3條,混沌工程可能導致線上功能不可用,甚至造成資損,所以在以找出系統弱點為目的的前提下,需要最小化故障影響範圍,並且當出現嚴重問題時可以迅速恢復,即故障是可控的。鑑於此,有時候可以引入A/B測試,最小化影響範圍。

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

階段一:分散式系統彈性化一般

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

  • 以有贊為例,由於我們才剛剛開始,為了控制風險,起初只會在測試環境實施混沌工程,所以暫時沒有可以參考的準確大盤資料,即合適的基準“穩定狀態”。但也不是不可能,觀察大盤資料可以認為反映的是系統巨集觀指標,從微觀角度來講,我們可以篩選出一批直接影響核心大盤資料(如註冊量、下單量等)的介面,在對系統實施混沌後執行這些介面的場景化整合測試,通過觀察測試結果來評估系統的可靠性,從而尋找系統弱點,這在測試環境是可行的。
    此外,混沌工程可以認為是通用型異常不定時不定目標不定異常型別的自動化實現,如果拋開這層,手動對目標機器注入特定的一種或多種異常,並輔以對應的異常恢復手段,那我們就可以在通用異常測試中應用。

階段二:分散式系統彈性化成熟

  • 以網飛為例,他們基本上已經在按照上述理想的步驟和原則實施混沌工程,工作日持續、自動的實施混沌工程,系統具備高度的可靠性,彈性伸縮。

有贊混沌工程的實現:

由於混沌工程主要是注入特定的事件並引起系統故障,既然是“幹壞事”的,所以我們將其命名成了“威震天”(變形金剛中的反派Boss)。由於我們還處於第一階段,所以故障的注入主要是人為控制,目前已實現的故障型別有:

  • CPU高負載
  • 磁碟高負載:頻繁讀寫磁碟
  • 磁碟空間不足
  • 優雅的下線應用:使用應用的stop指令碼平滑的停止應用
  • 通過kill程式直接停止應用,可能造成資料不一致
  • 網路惡化:隨機改變一些包資料,使資料內容不正確
  • 網路延遲:將包延遲一個特定範圍的時間
  • 網路丟包:構造一個tcp不會完全失敗的丟包率
  • 網路黑洞:忽略來自某個ip的包
  • 外部服務不可達:將外部服務的域名指向本地環回地址或將訪問外部服務的埠的OUTPUT資料包丟棄

參考文獻
PRINCIPLES OF CHAOS ENGINEERING

我的其他部落格
非同步系統的兩種測試方法

我的開源專案 —— 方便產品、開發、測試三方協同自測的管理工具
捉蟲記

ps: 有贊測試組在持續招人中,大量崗位空缺,只要你來,就能幫你點亮全棧開發技能樹,有意向換工作的同學可以發簡歷到 sunjun【@】youzan.com

混沌工程 - 軟體系統高可用、彈性化的必由之路

相關文章