微服務架構下的質量迷思——混沌工程

ThoughtWorks發表於2019-05-05

從2005年Peter Rodgers博士提出微web服務,到2014年ThoughtWorks首席科學家Martin Fowler與James Lewis共同提出微服務概念至今已多年,這期間也是網際網路及網際網路+發展的高速期,消費市場變化莫測,消費者也變得越來越挑剔,很多公司和產品由於無法跟上市場的快速變化而紛紛倒下。越來越多的網際網路巨頭甚至傳統行業都開始對自己的遺留系統進行微服務改造,通過把系統拆分為更加靈活、有業務邊界上下文、鬆散耦合、可獨立部署的服務來應對快速變化的消費市場。

微服務架構面臨的挑戰

通常情況下,對於複雜業務或遺留系統,我們可以通過領域驅動設計(DDD:Domain-Driven Design)有效的解決限界上下文劃分、服務邊界定義以及組織結構調整等問題。除了這些,我們的開發團隊還面臨著其他的挑戰:複雜的分散式系統、資料一致性、容錯設計、限流設計、艙壁設計等問題。那麼如此複雜的系統如何來保證系統“質量”呢?

長久以來,“測試金字塔”都是敏捷開發團隊保證專案交付質量的守則,而“測試金字塔”也確實從不同的維度涵蓋了方法呼叫、業務邏輯、使用者行為等方面。為了確保在進行復雜的呼叫和被呼叫時,服務之間能有一定程度上的一致性和快速反饋,我們會第一時間想到“契約測試”,“測試金字塔”也演化成了另一個樣子。

微服務架構下的質量迷思——混沌工程

下圖,我們聚焦於微服務架構的業務服務層,在API測試之外在基礎服務的呼叫方和提供方之間增加了契約測試:

微服務架構下的質量迷思——混沌工程

在微服務和前後端分離日趨流行的今天,契約測試的確可以在系統頻繁演進、重構的情況下保證服務間呼叫的可用性,而在“聚合服務層”通過API測試,可以暴露服務的組合過程中的問題。“儘早測試”可以讓團隊在初期發現更多的問題,降低後期修復成本,同時讓服務與服務之間具有“感知力”,任何與契約不符的業務變更都能被測試所感知。但是,既然契約測試是保證服務呼叫方和提供方的一致性,更直接說,是另一種對API的驗證,那麼契約測試只能覆蓋到業務邏輯維度,如果想更好開發或改造微服務系統,就需要相對深入的瞭解微服務有哪些特性:

微服務架構下的質量迷思——混沌工程

我們可以看到,這個簡單的圖中提到了一些微服務的特性(基於Spring Boot):客戶端負載均衡、微服務容錯保護、API服務閘道器、分散式鏈路跟蹤等,我們不對這些進行解釋,但毫無疑問,契約測試無法覆蓋和測試到這些特性,同時也無法模擬例如網路延遲、CPU滿載、請求異常、依賴故障、硬體故障等場景。對於一個不具備容錯能力的脆弱系統,即使我們可以對服務解耦、獨立部署,可對於使用者來說,體驗到的可能是一次又一次的“災難”。我們在質量活動中,總會聽到這樣的聲音:“不要動這個功能,會弄壞其他功能”、“客戶根本不會這麼操作“、”這個缺陷沒有意義,你這樣會把系統弄掛”。我們總是擔心繫統某些脆弱的環節掛掉,擔心某次操作讓整個系統當機。遺憾的是,墨菲定律告訴我們,“如果事情有變壞的可能,不管這種可能性有多小,它總會發生。”

之前一個發生在身邊的專案經歷大概是這樣的:一個團隊提供基礎服務,並承諾服務的功能、效能、彈性都沒有問題。在整合聯調時,由於對認證服務的呼叫超過負荷,對整個服務系統造成阻塞,導致雪崩效應,幾乎所有客戶端應用大面積癱瘓;另一個案例,由於沒有對一個內容服務進行熔斷保護,導致整個網站首頁無法載入。而發生在世界各地的IT災難也不少,某航空公司,由於排程和跟蹤系統出現問題,導致去年6月份七天內將近3000個航班取消,損失3500萬美金;“資訊災難總是普遍而沒有偏見地發生在各個領域和任何時候”。

既然我們沒有辦法避免災難的發生,最好的辦法就是“探索系統故障邊界,驗證系統災難恢復能力”。以往的“機房”時代的一些故障演練一般通過斷網、斷電模擬單點故障,來測試系統的恢復能力,而新型的分散式服務時代消除了單點故障,但也引入了更多複雜的問題,我們需要可靠性更強、容錯性和擴容性更高的系統。一種解決方案就是,我們需要一種有策略的、有方法的實踐方案對系統進行一定程度的“隨機破壞”,通過讓系統”感染“,來提升系統的”免疫力“。Netflix開發出Chaos Monkey來對系統進行隨機試驗來了解系統是否具有高可用性和容錯性,而由此便誕生出”混沌工程“。

什麼是混沌工程?混沌工程原則是什麼?

混沌工程是一種可試驗的、基於系統的方法來處理大規模分散式系統中的混亂問題。通過不斷試驗,瞭解系統的實際能承受的韌性邊界並建立信心,通過不同的試驗方法和目的,觀察分散式系統的行為和反應。一句話——以試驗的方法儘早揭露系統弱點

混沌工程類似於“故障演練”,不侷限於測試,而更像是工程實踐。為什麼這麼說,通常的測試用例會有“期望結果”和“實際結果”,通過將兩個結果比較,或者對使用者行為的預期,來判斷測試通過或失敗。而混沌試驗類似於”探索性測試“,試驗本身沒有明確是輸入和預期結果,通過對系統和服務的干預,來觀察系統的”反應“。我們將混沌工程原則融入在試驗過程中:在生產環境小規模模擬系統故障並定期自動化執行試驗,通過試驗結果與正常結果進行比對,觀察系統”邊界“。

微服務架構下的質量迷思——混沌工程

通過“測試金字塔”和混沌試驗,從業務邏輯和系統高可用性兩個維度對微服務系統進行觀察和測試,兩種方案結合形成了一種更全面的實踐,我稱之為“服務級質量內建實踐”(BQIS——Build Qualify in Services)。不論企業是在微服務改造期還是中臺戰略部署期,混沌實踐能夠有效避免生產環境災難,提升系統的容錯率和可用性。

如何引入混沌工程?

在眾多服務化改造案例中,Netflix無疑是最成功的公司之一,該公司的很多試驗工具也都整合在Spring Cloud中,成為微服務框架的標準。而Chaos Monkey就是Netflix進行混沌試驗一個重要工具。作為國內的電商巨頭,服務化和中臺戰略的先行者阿里,近期也開源了他們自己的混沌試驗注入工具ChaosBlade。

“混沌工程”的引入受限於組織文化的接受程度,任何一種工程實踐和方法論的落地都無法一蹴而就。但是我們依然可以通過裁剪,在組織的安全範圍內進行逐步嘗試。不管是線上上環境還是測試環境,我們都需要先搞清楚,目前的混沌工具都為我們提供了哪些方法。

Spring Cloud是時下最流行的分散式微服務架構下的一站式解決方案之一,它方便快速的將Spring Boot的微服務有效的管理起來,並提供了包括負載均衡、全鏈路監控、服務閘道器以及眾多基於Netflix的開源工具。除此之外,鑑於Netflix在服務化演進中的成功案例,我們來了解下Netflix開源的混沌工程試驗框架Chaos Monkey究竟是什麼?

在Spring Boot工程中,對需要進行試驗的服務application.yml檔案的Chaos Monkey進行配置:

微服務架構下的質量迷思——混沌工程

從配置檔案中我們可以很容易看到,Chaos Monkey的三種襲擊方式——延時、異常和程式終止,同時我們也可以設定一個數值範圍,在對服務進行延時攻擊時生成隨機延時。預設攻擊方式為延時攻擊,當同時開啟異常攻擊時,程式攻擊則不會發生。Level:N表示第N個請求將被攻擊,N=1時,表示每個請求都會被攻擊,當同時開啟異常攻擊時,與N值無關,表示每個請求都將被攻擊。

ChaosBlade提供的攻擊也很豐富,使用方式對開發人員來說更友好:

微服務架構下的質量迷思——混沌工程

通過命令列對CPU、硬碟、網路進行試驗,也可以對相應的服務進行類似的例如延時攻擊試驗:

微服務架構下的質量迷思——混沌工程

利用效能測試工具例如Jmeter或Gatling,對於API進行測試,例如POST /product?des=phone,通過效能測試報告對比API效能指標以及Hystrix監控分析相關服務“反應”,同時也可以通過Grafana和CloudWatch監控各個系統引數來和“穩定基線資料”進行比較和觀察。

混沌試驗示例

試驗一:

1.確定目標和範圍,觀察CPU利用率基線:(CPU平均利用率低於20%)

微服務架構下的質量迷思——混沌工程

觀察API延時基線:(可以看到API-1和API-2平均延時低於300ms,API-3在300ms-700ms之間)

微服務架構下的質量迷思——混沌工程

2.設計實驗資料和方案,我們對幾個例項進行CPU滿載攻擊:

微服務架構下的質量迷思——混沌工程

觀察CPU利用率:

微服務架構下的質量迷思——混沌工程

觀察API延時:(API請求延時變化明顯,API-3延時更加嚴重)

微服務架構下的質量迷思——混沌工程

試驗二:測試服務熔斷機制

示例專案架構:Eureka服務發現註冊,一個PROVIDER-SERVICE且有兩個例項,一個CONSUMER-SERVICE,也可以通過zipkin之類的分散式跟蹤系統也可以看到服務呼叫關係。

微服務架構下的質量迷思——混沌工程

1.對PROVIDER-SERVICE的例項2進行延時攻擊:

微服務架構下的質量迷思——混沌工程

2.檢視PROVIDER-SERVICE instance 2的延時是否生效。通過postman測試,可以看到API響應為30s:

微服務架構下的質量迷思——混沌工程

3.客戶端請求相同的API:

微服務架構下的質量迷思——混沌工程

觀察結果:負載均衡生效,請求成功,熔斷器關閉

4.殺掉instance 1之後請求相同API:

微服務架構下的質量迷思——混沌工程

觀察結果:請求超時,熔斷器關閉

5.連續且請求相同API:

微服務架構下的質量迷思——混沌工程

觀察結果:部分請求被立刻拒絕,加速服務失敗的判定,熔斷器開啟

6.殺掉instance 2請求API:

微服務架構下的質量迷思——混沌工程

觀察結果:fallback機制生效,返回相應邏輯。

這些只是混沌工程的簡單使用方法,在實際專案中需要根據專案架構、業務複雜度、呼叫場景等設計試驗細節。

總結

從業務的橫切面到對微服務系統的縱切面觀察,“契約測試”固然重要,但並不能代表微服務質量保證的全部。“蠻力”可以從某種意義上解決很多問題,但並不能催化出更高階解決方案。同樣,也只有瞭解到微服務的實現方式和原理才能夠更好的理解系統並實施更有效的質量解決方案。

Netflix對混沌工程的成熟度從“複雜度”和“接受度”兩個方面給出了定義,可以看到,混沌工程或試驗不單單是方法論的引入,更是實踐上的滲透。用“Immersion”解釋更加確切,與敏捷實踐類似,這樣的“服務級質量內建試驗”對團隊來說開始無疑是一種挑戰,但隨著越來越多的問題更快、更早的視覺化給團隊,使組織和客戶對我們構建和改造中的系統越來越有信心。通過小規模實踐到大規模改造,混沌工程不是為了測試,更不是為了引入工具, 混沌工程會像一種文化,將擴散於範圍更廣的團隊和組織。


文/ThoughtWorks樑真

更多精彩洞見,請關注微信公眾號:ThoughtWorks洞見

相關文章