一文理解微服务架构下的系统可用性如何保证?
從2005年P(guān)eter Rodgers博士提出微web服務,到2014年ThoughtWorks首席科學家Martin Fowler與James Lewis共同提出微服務概念至今已多年,這期間也是互聯(lián)網(wǎng)及互聯(lián)網(wǎng)+發(fā)展的高速期,消費市場變化莫測,消費者也變得越來越挑剔,很多公司和產(chǎn)品由于無法跟上市場的快速變化而紛紛倒下。越來越多的互聯(lián)網(wǎng)巨頭甚至傳統(tǒng)行業(yè)都開始對自己的遺留系統(tǒng)進行微服務改造,通過把系統(tǒng)拆分為更加靈活、有業(yè)務邊界上下文、松散耦合、可獨立部署的服務來應對快速變化的消費市場。
微服務架構(gòu)面臨的挑戰(zhàn)
通常情況下,對于復雜業(yè)務或遺留系統(tǒng),我們可以通過領(lǐng)域驅(qū)動設計(DDD:Domain-Driven Design)有效的解決限界上下文劃分、服務邊界定義以及組織結(jié)構(gòu)調(diào)整等問題。除了這些,我們的開發(fā)團隊還面臨著其他的挑戰(zhàn):復雜的分布式系統(tǒng)、數(shù)據(jù)一致性、容錯設計、限流設計、艙壁設計等問題。那么如此復雜的系統(tǒng)如何來保證系統(tǒng)“質(zhì)量”呢?
長久以來,“測試金字塔”都是敏捷開發(fā)團隊保證項目交付質(zhì)量的守則,而“測試金字塔”也確實從不同的維度涵蓋了方法調(diào)用、業(yè)務邏輯、用戶行為等方面。為了確保在進行復雜的調(diào)用和被調(diào)用時,服務之間能有一定程度上的一致性和快速反饋,我們會第一時間想到“契約測試”,“測試金字塔”也演化成了另一個樣子。
下圖,我們聚焦于微服務架構(gòu)的業(yè)務服務層,在API測試之外在基礎服務的調(diào)用方和提供方之間增加了契約測試:
在微服務和前后端分離日趨流行的今天,契約測試的確可以在系統(tǒng)頻繁演進、重構(gòu)的情況下保證服務間調(diào)用的可用性,而在“聚合服務層”通過API測試,可以暴露服務的組合過程中的問題。“盡早測試”可以讓團隊在初期發(fā)現(xiàn)更多的問題,降低后期修復成本,同時讓服務與服務之間具有“感知力”,任何與契約不符的業(yè)務變更都能被測試所感知。但是,既然契約測試是保證服務調(diào)用方和提供方的一致性,更直接說,是另一種對API的驗證,那么契約測試只能覆蓋到業(yè)務邏輯維度,如果想更好開發(fā)或改造微服務系統(tǒng),就需要相對深入的了解微服務有哪些特性:
我們可以看到,這個簡單的圖中提到了一些微服務的特性(基于Spring Boot):客戶端負載均衡、微服務容錯保護、API服務網(wǎng)關(guān)、分布式鏈路跟蹤等,我們不對這些進行解釋,但毫無疑問,契約測試無法覆蓋和測試到這些特性,同時也無法模擬例如網(wǎng)絡延遲、CPU滿載、請求異常、依賴故障、硬件故障等場景。對于一個不具備容錯能力的脆弱系統(tǒng),即使我們可以對服務解耦、獨立部署,可對于用戶來說,體驗到的可能是一次又一次的“災難”。我們在質(zhì)量活動中,總會聽到這樣的聲音:“不要動這個功能,會弄壞其他功能”、“客戶根本不會這么操作“、”這個缺陷沒有意義,你這樣會把系統(tǒng)弄掛”。我們總是擔心系統(tǒng)某些脆弱的環(huán)節(jié)掛掉,擔心某次操作讓整個系統(tǒng)宕機。遺憾的是,墨菲定律告訴我們,“如果事情有變壞的可能,不管這種可能性有多小,它總會發(fā)生。”
之前一個發(fā)生在身邊的項目經(jīng)歷大概是這樣的:一個團隊提供基礎服務,并承諾服務的功能、性能、彈性都沒有問題。在集成聯(lián)調(diào)時,由于對認證服務的調(diào)用超過負荷,對整個服務系統(tǒng)造成阻塞,導致雪崩效應,幾乎所有客戶端應用大面積癱瘓;另一個案例,由于沒有對一個內(nèi)容服務進行熔斷保護,導致整個網(wǎng)站首頁無法加載。而發(fā)生在世界各地的IT災難也不少,某航空公司,由于調(diào)度和跟蹤系統(tǒng)出現(xiàn)問題,導致去年6月份七天內(nèi)將近3000個航班取消,損失3500萬美金;“信息災難總是普遍而沒有偏見地發(fā)生在各個領(lǐng)域和任何時候”。
既然我們沒有辦法避免災難的發(fā)生,最好的辦法就是“探索系統(tǒng)故障邊界,驗證系統(tǒng)災難恢復能力”。以往的“機房”時代的一些故障演練一般通過斷網(wǎng)、斷電模擬單點故障,來測試系統(tǒng)的恢復能力,而新型的分布式服務時代消除了單點故障,但也引入了更多復雜的問題,我們需要可靠性更強、容錯性和擴容性更高的系統(tǒng)。一種解決方案就是,我們需要一種有策略的、有方法的實踐方案對系統(tǒng)進行一定程度的“隨機破壞”,通過讓系統(tǒng)”感染“,來提升系統(tǒng)的”免疫力“。Netflix開發(fā)出Chaos Monkey來對系統(tǒng)進行隨機試驗來了解系統(tǒng)是否具有高可用性和容錯性,而由此便誕生出”混沌工程“。
什么是混沌工程?混沌工程原則是什么?
混沌工程是一種可試驗的、基于系統(tǒng)的方法來處理大規(guī)模分布式系統(tǒng)中的混亂問題。通過不斷試驗,了解系統(tǒng)的實際能承受的韌性邊界并建立信心,通過不同的試驗方法和目的,觀察分布式系統(tǒng)的行為和反應。一句話——以試驗的方法盡早揭露系統(tǒng)弱點。
混沌工程類似于“故障演練”,不局限于測試,而更像是工程實踐。為什么這么說,通常的測試用例會有“期望結(jié)果”和“實際結(jié)果”,通過將兩個結(jié)果比較,或者對用戶行為的預期,來判斷測試通過或失敗。而混沌試驗類似于”探索性測試“,試驗本身沒有明確是輸入和預期結(jié)果,通過對系統(tǒng)和服務的干預,來觀察系統(tǒng)的”反應“。我們將混沌工程原則融入在試驗過程中:在生產(chǎn)環(huán)境小規(guī)模模擬系統(tǒng)故障并定期自動化執(zhí)行試驗,通過試驗結(jié)果與正常結(jié)果進行比對,觀察系統(tǒng)”邊界“。
通過“測試金字塔”和混沌試驗,從業(yè)務邏輯和系統(tǒng)高可用性兩個維度對微服務系統(tǒng)進行觀察和測試,兩種方案結(jié)合形成了一種更全面的實踐,我稱之為“服務級質(zhì)量內(nèi)建實踐”(BQIS——Build Qualify in Services)。不論企業(yè)是在微服務改造期還是中臺戰(zhàn)略部署期,混沌實踐能夠有效避免生產(chǎn)環(huán)境災難,提升系統(tǒng)的容錯率和可用性。
如何引入混沌工程?
在眾多服務化改造案例中,Netflix無疑是最成功的公司之一,該公司的很多試驗工具也都集成在Spring Cloud中,成為微服務框架的標準。而Chaos Monkey就是Netflix進行混沌試驗一個重要工具。作為國內(nèi)的電商巨頭,服務化和中臺戰(zhàn)略的先行者阿里,近期也開源了他們自己的混沌試驗注入工具ChaosBlade。
“混沌工程”的引入受限于組織文化的接受程度,任何一種工程實踐和方法論的落地都無法一蹴而就。但是我們依然可以通過裁剪,在組織的安全范圍內(nèi)進行逐步嘗試。不管是在線上環(huán)境還是測試環(huán)境,我們都需要先搞清楚,目前的混沌工具都為我們提供了哪些方法。
Spring Cloud是時下最流行的分布式微服務架構(gòu)下的一站式解決方案之一,它方便快速的將Spring Boot的微服務有效的管理起來,并提供了包括負載均衡、全鏈路監(jiān)控、服務網(wǎng)關(guān)以及眾多基于Netflix的開源工具。除此之外,鑒于Netflix在服務化演進中的成功案例,我們來了解下Netflix開源的混沌工程試驗框架Chaos Monkey究竟是什么?
在Spring Boot工程中,對需要進行試驗的服務application.yml文件的Chaos Monkey進行配置:
從配置文件中我們可以很容易看到,Chaos Monkey的三種襲擊方式——延時、異常和進程終止,同時我們也可以設置一個數(shù)值范圍,在對服務進行延時攻擊時生成隨機延時。默認攻擊方式為延時攻擊,當同時開啟異常攻擊時,進程攻擊則不會發(fā)生。Level:N表示第N個請求將被攻擊,N=1時,表示每個請求都會被攻擊,當同時開啟異常攻擊時,與N值無關(guān),表示每個請求都將被攻擊。
ChaosBlade提供的攻擊也很豐富,使用方式對開發(fā)人員來說更友好:
通過命令行對CPU、硬盤、網(wǎng)絡進行試驗,也可以對相應的服務進行類似的例如延時攻擊試驗:
利用性能測試工具例如Jmeter或Gatling,對于API進行測試,例如POST /product?des=phone,通過性能測試報告對比API性能指標以及Hystrix監(jiān)控分析相關(guān)服務“反應”,同時也可以通過Grafana和CloudWatch監(jiān)控各個系統(tǒng)參數(shù)來和“穩(wěn)定基線數(shù)據(jù)”進行比較和觀察。
混沌試驗示例
試驗一:
1.確定目標和范圍,觀察CPU利用率基線:(CPU平均利用率低于20%)
觀察API延時基線:(可以看到API-1和API-2平均延時低于300ms,API-3在300ms-700ms之間)
2.設計實驗數(shù)據(jù)和方案,我們對幾個實例進行CPU滿載攻擊:
觀察CPU利用率:
觀察API延時:(API請求延時變化明顯,API-3延時更加嚴重)
試驗二:測試服務熔斷機制
示例項目架構(gòu):Eureka服務發(fā)現(xiàn)注冊,一個PROVIDER-SERVICE且有兩個實例,一個CONSUMER-SERVICE,也可以通過zipkin之類的分布式跟蹤系統(tǒng)也可以看到服務調(diào)用關(guān)系。
1.對PROVIDER-SERVICE的實例2進行延時攻擊:
2.查看PROVIDER-SERVICE instance 2的延時是否生效。通過postman測試,可以看到API響應為30s:
3.客戶端請求相同的API:
觀察結(jié)果:負載均衡生效,請求成功,熔斷器關(guān)閉
4.殺掉instance 1之后請求相同API:
觀察結(jié)果:請求超時,熔斷器關(guān)閉
5.連續(xù)且請求相同API:
觀察結(jié)果:部分請求被立刻拒絕,加速服務失敗的判定,熔斷器開啟
6.殺掉instance 2請求API:
觀察結(jié)果:fallback機制生效,返回相應邏輯。
這些只是混沌工程的簡單使用方法,在實際項目中需要根據(jù)項目架構(gòu)、業(yè)務復雜度、調(diào)用場景等設計試驗細節(jié)。
總結(jié)
從業(yè)務的橫切面到對微服務系統(tǒng)的縱切面觀察,“契約測試”固然重要,但并不能代表微服務質(zhì)量保證的全部。“蠻力”可以從某種意義上解決很多問題,但并不能催化出更高階解決方案。同樣,也只有了解到微服務的實現(xiàn)方式和原理才能夠更好的理解系統(tǒng)并實施更有效的質(zhì)量解決方案。
Netflix對混沌工程的成熟度從“復雜度”和“接受度”兩個方面給出了定義,可以看到,混沌工程或試驗不單單是方法論的引入,更是實踐上的滲透。用“Immersion”解釋更加確切,與敏捷實踐類似,這樣的“服務級質(zhì)量內(nèi)建試驗”對團隊來說開始無疑是一種挑戰(zhàn),但隨著越來越多的問題更快、更早的可視化給團隊,使組織和客戶對我們構(gòu)建和改造中的系統(tǒng)越來越有信心。通過小規(guī)模實踐到大規(guī)模改造,混沌工程不是為了測試,更不是為了引入工具, 混沌工程會像一種文化,將擴散于范圍更廣的團隊和組織。
總結(jié)
以上是生活随笔為你收集整理的一文理解微服务架构下的系统可用性如何保证?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一个Java对象到底占用多大内存?
- 下一篇: 拯救 Out Of Memory,8个案