微服務(wù)平臺(tái)可靠性設(shè)計(jì)_第1頁(yè)
微服務(wù)平臺(tái)可靠性設(shè)計(jì)_第2頁(yè)
微服務(wù)平臺(tái)可靠性設(shè)計(jì)_第3頁(yè)
微服務(wù)平臺(tái)可靠性設(shè)計(jì)_第4頁(yè)
微服務(wù)平臺(tái)可靠性設(shè)計(jì)_第5頁(yè)
已閱讀5頁(yè),還剩26頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、微服務(wù)平臺(tái)可靠性設(shè)計(jì)Microservices目錄 TOC o 1-5 h z 背景5無(wú)處不在的故障 5分布式部署和調(diào)用 5大型系統(tǒng)微服務(wù)進(jìn)程內(nèi)合設(shè) 6微服務(wù)健康度 7同步的I/O操彳 8第三方SDK API調(diào)用 9微服務(wù)可靠性9關(guān)鍵的可靠性因素 10 HYPERLINK l bookmark12 o Current Document 異步I/O操作10網(wǎng)絡(luò)I/O 10使用同步阻塞I/O的問題10使用非阻塞I/O 通信 11磁盤 I/O 12數(shù)據(jù)庫(kù)操作15故障隔離16通信鏈路隔離16調(diào)度資源隔離18微服務(wù)之間隔離 18第三方依賴隔離19進(jìn)程級(jí)隔離 19容器隔離 19VM 隔離20集群容錯(cuò)21路

2、由容錯(cuò)21服務(wù)降級(jí)21強(qiáng)制降級(jí)22容錯(cuò)降級(jí)22服務(wù)降級(jí)Portal 23熔斷機(jī)制23工作原理24微服務(wù)健康度25流量控制25動(dòng)態(tài)流控26靜態(tài)流控27用戶自定義流控機(jī)制 27 HYPERLINK l bookmark47 o Current Document 使用Hystrix提升微服務(wù)可靠性28Hystrix 簡(jiǎn)介28Hystrix的核心功能28依賴隔離28熔斷器29優(yōu)雅降級(jí)30Reactive編程31信號(hào)量隔離31集成 Hystrix 32集成架構(gòu)32集成Hystrix 帶來(lái)的優(yōu)點(diǎn) 33附錄33參考文獻(xiàn)33微服務(wù)化之后,系統(tǒng)分布式部署,傳統(tǒng)單個(gè)流程的本地API調(diào)用被拆分成多個(gè)微服務(wù)之間的跨網(wǎng)

3、絡(luò)調(diào)用,由于引入了網(wǎng)絡(luò)通信、 序列化和反序列化等操作,系統(tǒng)發(fā)生故障的概率提高了很多。微服務(wù)故障,有些是由于業(yè)務(wù)自身設(shè)計(jì)或者編碼不當(dāng)導(dǎo)致,有些是底層的微服務(wù)化框架容錯(cuò)能力不足導(dǎo)致。在實(shí)際項(xiàng)目中,需要從業(yè)務(wù)和平臺(tái)兩方面入手,提升微服務(wù)的可靠性。無(wú)處不在的故障分布式部署和調(diào)用傳統(tǒng)單體架構(gòu)一個(gè)完整的業(yè)務(wù)流程往往在同一個(gè)進(jìn)程內(nèi)部完成處理,不需要進(jìn)行分布式協(xié)作,它的工作原理如下所示:消巷者本地方法本地方法進(jìn)程圖1-1傳統(tǒng)單體架構(gòu)本地方法調(diào)用微服務(wù)化之后,不同的微服務(wù)采用分布式集群部署方式,服務(wù)的消費(fèi)者和提供者通常運(yùn)行在不同的進(jìn)程中,需要跨網(wǎng)絡(luò)做RPC調(diào)用,它的工作原理如下所示:圖1-2微服務(wù)分布式RPC調(diào)

4、用分布式調(diào)用之后,相比于傳統(tǒng)單體架構(gòu)的本地方法調(diào)用,主要引入了如下潛在故障點(diǎn):序列化與反序列化:微服務(wù)的請(qǐng)求和應(yīng)答都需要經(jīng)過序列化和反序列化,做消息的跨網(wǎng)絡(luò)通信,由于數(shù)據(jù)結(jié)構(gòu)不一致、不支持的數(shù)據(jù)類型、對(duì)方編解碼錯(cuò)誤等都會(huì)導(dǎo)致序列化和反序列化失敗,進(jìn)而導(dǎo)致微服務(wù)調(diào)用失敗。網(wǎng)絡(luò)問題:常見的包括網(wǎng)絡(luò)超時(shí)、網(wǎng)絡(luò)閃斷、網(wǎng)絡(luò)單通、網(wǎng)絡(luò)擁塞等,都可能會(huì)導(dǎo)致微服務(wù)遠(yuǎn)程調(diào)用的失敗。大型系統(tǒng)微服務(wù)進(jìn)程內(nèi)合設(shè)理想情況下,每個(gè)微服務(wù)都獨(dú)立打包和部署,微服務(wù)之間天然就支持進(jìn)程級(jí)隔離,但事實(shí)上,對(duì)于一個(gè)大規(guī)模的企業(yè)IT系統(tǒng)、或者大型網(wǎng)站,是由成百上千個(gè)微服務(wù)組成的,在實(shí)踐中,微服務(wù)通常是不可能做到百分之百獨(dú)立部署的,原因

5、如下:.方便開發(fā):通常會(huì)按照業(yè)務(wù)域劃分團(tuán)隊(duì),同一個(gè)業(yè)務(wù)域往往包含多個(gè)微服務(wù),由一個(gè)團(tuán)隊(duì)負(fù)責(zé)開發(fā)。為了方便CI/CD ,同一業(yè)務(wù)域的微服務(wù)往往打包和部署在一起,而不是每個(gè)微服務(wù)獨(dú)立打包部署。.方便運(yùn)維:海量的微服務(wù)進(jìn)程(以 1000個(gè)微服務(wù)*10個(gè)進(jìn)程實(shí)例為例),會(huì)增加部 署、數(shù)據(jù)采集(性能 KPI和日志等)、告警、問題定位等成本,如果運(yùn)維自動(dòng)化程度 不高,很難支撐大規(guī)模的微服務(wù)獨(dú)立部署。.提升性能:一些業(yè)務(wù)對(duì)時(shí)延非常敏感,如果該業(yè)務(wù)鏈上的所有微服務(wù)調(diào)用都跨網(wǎng)絡(luò)通信, 時(shí)延往往無(wú)法滿足業(yè)務(wù)要求。通過將微服務(wù)合設(shè)在同一個(gè)進(jìn)程之內(nèi),利用路由短路,把RPC調(diào)用轉(zhuǎn)化成本地方法調(diào)用,可以極大的提升性能。.

6、簡(jiǎn)化分布式事務(wù)處理:分布式部署之后,會(huì)帶來(lái)分布式事務(wù)問題。有時(shí)候業(yè)務(wù)為了簡(jiǎn)化 分布式事務(wù)的處理,將事務(wù)相關(guān)的微服務(wù)部署在同一個(gè)進(jìn)程中,把分布式事務(wù)轉(zhuǎn)換成本地事務(wù),簡(jiǎn)化事務(wù)處理。不同的微服務(wù)合設(shè)在同一個(gè)進(jìn)程之中,就會(huì)引入一系列潛在的故障點(diǎn),例如:處理較慢的微服務(wù)會(huì)阻塞其它微服務(wù)某個(gè)微服務(wù)故障蔓延,可能導(dǎo)致整個(gè)進(jìn)程不可用低優(yōu)先級(jí)的微服務(wù),搶占高優(yōu)先級(jí)微服務(wù)的資源微服務(wù)健康度傳統(tǒng)情況下,往往使用服務(wù)注冊(cè)中心檢測(cè)微服務(wù)的狀態(tài),當(dāng)檢測(cè)到服務(wù)提供者不可用時(shí),會(huì)將故障的服務(wù)信息廣播到集群所有節(jié)點(diǎn),消費(fèi)者接收到服務(wù)故障通知消息之后,根據(jù)故障信息中的服務(wù)名稱、IP地址等信息,對(duì)故障節(jié)點(diǎn)進(jìn)行隔離。它的工作原理如下

7、所示:圖1-3微服務(wù)狀態(tài)檢測(cè)使用基于心跳或者會(huì)話的微服務(wù)狀態(tài)檢測(cè),可以發(fā)現(xiàn)微服務(wù)所在進(jìn)程宕機(jī)、網(wǎng)絡(luò)故障等問題,但在實(shí)際業(yè)務(wù)中,微服務(wù)并非“非死即活”,它可能處于“亞健康狀態(tài)”,服務(wù)調(diào) 用失敗率很高,但又不是全部失敗。或者微服務(wù)已經(jīng)處于過負(fù)荷流控狀態(tài),業(yè)務(wù)質(zhì)量受損, 但是又沒有全部中斷。使用簡(jiǎn)單的微服務(wù)狀態(tài)檢測(cè),很難應(yīng)對(duì)上述這些場(chǎng)景。 通過對(duì)微服務(wù)的運(yùn)行質(zhì)量建模,利用微服務(wù)健康度模型,根據(jù)采集的各種指標(biāo)對(duì)微服務(wù)健康度實(shí)時(shí)打分,依據(jù)打分結(jié)果采取相應(yīng)的可靠性對(duì)策,可以更有針對(duì)性的保障系統(tǒng)的可靠性。同步的I/O操作在整個(gè)微服務(wù)調(diào)用過程中,主要會(huì)涉及到三類 I/O操作:網(wǎng)絡(luò)I/O操作,涉及到網(wǎng)絡(luò)讀寫磁盤

8、I/O操作,主要是記錄日志、話單、寫本地文件等數(shù)據(jù)庫(kù)訪問,例如 Java使用JDBC驅(qū)動(dòng)進(jìn)行數(shù)據(jù)庫(kù)操作凡是涉及到I/O操作的,如果I/O操作是同步阻塞模式,例如 Java的BIO、文件File 的讀寫操作、數(shù)據(jù)庫(kù)訪問的JDBC接口等,都是同步阻塞的。只要訪問的網(wǎng)絡(luò)、磁盤或者數(shù)據(jù)庫(kù)實(shí)例比較慢,都會(huì)導(dǎo)致調(diào)用方線程的阻塞。由于線程是 Java虛擬機(jī)比較重要的資源, 當(dāng)大量微服務(wù)調(diào)用線程被阻塞之后,系統(tǒng)的吞吐量將嚴(yán)重下降。第三方SDK API調(diào)用在微服務(wù)中,調(diào)用第三方 SDK API,也可能會(huì)引入新的故障點(diǎn),例如通過FTP客戶端訪問遠(yuǎn)端的FTP服務(wù),或者使用MQ客戶端訪問MQ服務(wù),如果這些客戶端 AP

9、I的容錯(cuò)性 設(shè)計(jì)不好,也會(huì)導(dǎo)致調(diào)用方的級(jí)聯(lián)故障,這些故障是潛在和隱性的,在設(shè)計(jì)的時(shí)候往往容易被忽視,但它帶來(lái)的風(fēng)險(xiǎn)和危害是巨大的。微服務(wù)可靠性軟件可靠性是指在給定時(shí)間內(nèi),特定環(huán)境下軟件無(wú)錯(cuò)運(yùn)行的概率。軟件可靠性包含了 以下三個(gè)要素:1)規(guī)定的時(shí)間:軟件可靠性只是體現(xiàn)在其運(yùn)行階段,所以將運(yùn)行時(shí)間作為規(guī)定的時(shí)間的度量。運(yùn)行時(shí)間包括軟件系統(tǒng)運(yùn)行后工作與掛起(啟動(dòng)但空閑)的累計(jì)時(shí)間。由于軟件運(yùn)行9的環(huán)境與程序路徑選取的隨機(jī)性,軟件的失效為隨機(jī)事件,所以運(yùn)行時(shí)間屬于隨機(jī)變量。2)規(guī)定的環(huán)境條件:環(huán)境條件指軟件的運(yùn)行環(huán)境。它涉及軟件系統(tǒng)運(yùn)行時(shí)所需的各種支持要素,如支持硬件、操作系統(tǒng)、其它支持軟件、輸入數(shù)據(jù)

10、格式和范圍以及操作規(guī)程等。3)規(guī)定的功能:軟件可靠性還與規(guī)定的任務(wù)和功能有關(guān)。由于要完成的任務(wù)不同,則調(diào)用的子模塊就不同(即程序路徑選擇不同),其可靠性也就可能不同。所以要準(zhǔn)確度量軟件 系統(tǒng)的可靠性必須首先明確它的任務(wù)和功能。關(guān)鍵的可靠性因素微服務(wù)的運(yùn)行質(zhì)量,除了自身的可靠性因素之外,還受到其它因素的影響, 包括網(wǎng)絡(luò)、數(shù)據(jù)庫(kù)訪問、其它相關(guān)聯(lián)的微服務(wù)運(yùn)行質(zhì)量等。微服務(wù)的可靠性設(shè)計(jì), 需要考慮上述綜合因素,總結(jié)如下:頭睢垂河司珞熔新親油曲建段也力異步1q掂作 打拈醫(yī)圖1-5微服務(wù)可靠性設(shè)計(jì)模型異步I/O操作 網(wǎng)絡(luò)I/O使用同步阻塞I/O的問題以Java為例,在JDK 1.4推出JAVA NIO1.

11、0 之前,基于 JAVA的所有Socket通信都采用了同步阻塞模式(BIO),這種一請(qǐng)求一應(yīng)答的通信模型簡(jiǎn)化了上層的應(yīng)用開發(fā),但是10在可靠性和性能方面存在巨大的弊端:Web BzrciigeTWeb BrowserWeb BrowstrSVcb Browse1 connect *Z coimocT3 connect :conn ecf2-1傳統(tǒng)Java同步阻塞I/O模型采用BIO通信模型的服務(wù)端,通常由一個(gè)獨(dú)立的 Acceptor線程負(fù)責(zé)監(jiān)聽客戶端的連接,接收到客戶端連接之后為客戶端連接創(chuàng)建一個(gè)新的線程處理請(qǐng)求消息,處理完成之后,返回應(yīng)答消息給客戶端,線程銷毀,這就是典型的一請(qǐng)求一應(yīng)答模型。

12、該架構(gòu)最大的問題就是不具備彈性伸縮能力,當(dāng)并發(fā)訪問量增加后,服務(wù)端的線程個(gè)數(shù)和并發(fā)訪問數(shù)成線性正比,由于線程是JAVA虛擬機(jī)非常寶貴的系統(tǒng)資源,當(dāng)線程數(shù)膨脹之后,系統(tǒng)的性能急劇下降,隨著并發(fā)量的繼續(xù)增加,可能會(huì)發(fā)生句柄溢出、線程堆棧溢出等問題,并導(dǎo)致服務(wù)器最終宕機(jī)。使用非阻塞I/O通信微服務(wù)進(jìn)行遠(yuǎn)程通信時(shí),通過使用非阻塞I/O ,可以解決由于網(wǎng)絡(luò)時(shí)延大、高并發(fā)接入等導(dǎo)致的服務(wù)端線程數(shù)膨脹或者線程被阻塞等問題。以Java為例,從JDK1.4開始,JDK提供了一套專門的類庫(kù)支持非阻塞 I/O ,可以在 java.nio包及其子包中找到相關(guān)的類和接口。JDK1.7之后,又提供了 NIO2.0類庫(kù),支

13、持異步I/O操作。利用JDK的異步非阻塞I/O ,可以實(shí)現(xiàn)一個(gè)I/O線程同時(shí)處理多個(gè)客戶端鏈路,讀寫操作不會(huì)因?yàn)榫W(wǎng)絡(luò)原因被阻塞,I/O線程可以高效的并發(fā)處理多個(gè)客戶端鏈路,實(shí)現(xiàn)I/O多11路復(fù)用,它的工作原理如下所示:2-2 Java非阻塞I/O模型使用非阻塞I/O進(jìn)行通信,以Java語(yǔ)言為例,建議策略如下:TCP私有協(xié)議:建議直接基于Netty開發(fā)。HTTP/Restful/SOAP 等:選擇支持非阻塞I/O的Web框架。也可以選擇基于Netty構(gòu)建的開源應(yīng)用層協(xié)議棧框架,例如支持異步Restful的RestExpress 。磁盤I/O微服務(wù)對(duì)磁盤I/O的操作分為兩類:直接文件操作:例如調(diào)用

14、File的open、write、read等接口,進(jìn)行文件操作。間接文件操作:例如調(diào)用日志類庫(kù)寫日志,雖然微服務(wù)并沒有直接操作日志文件,但是日志類庫(kù)底層還是會(huì)進(jìn)行文件的讀寫等操作。在實(shí)際項(xiàng)目中,最容易被忽視的就是日志操作。不同的日志類庫(kù),寫日志的機(jī)制不同,以Log4j 1.2.X 版本為例,當(dāng)日志隊(duì)列滿之后,有多種策略:同步等待,直到新的日志消息能夠入隊(duì)列,它會(huì)阻塞當(dāng)前業(yè)務(wù)線程。丟棄當(dāng)前的日志消息,不會(huì)阻塞當(dāng)前業(yè)務(wù)線程。不入隊(duì)列,由當(dāng)前調(diào)用寫日志的業(yè)務(wù)線程執(zhí)行日志I/O操作,如果此時(shí)磁盤I/O寫入12速度慢,則會(huì)阻塞當(dāng)前業(yè)務(wù)線程。在實(shí)際生產(chǎn)環(huán)境中, 我們就遇到過類似問題, 在某些時(shí)段,磁盤WIO

15、達(dá)到10+持續(xù)幾 秒鐘-10幾秒鐘,然后又恢復(fù)正常。WIO較高的時(shí)段,需要寫接口日志、話單等,由于系統(tǒng)默認(rèn)采用的是同步等待策略, 結(jié)果導(dǎo)致通信I/O線程、微服務(wù)調(diào)度線程等都被阻塞, 最終 鏈路因?yàn)樾奶瑫r(shí)被強(qiáng)制關(guān)閉、 微服務(wù)被大量阻塞在消息隊(duì)列中導(dǎo)致內(nèi)存居高不小、響應(yīng)超時(shí)等。由于偶現(xiàn)的 WIO高導(dǎo)致同步寫日志被阻塞,繼而引起通信線程、 微服務(wù)調(diào)用線程級(jí)聯(lián)故障,定位起來(lái)非常困難,平時(shí) Code Review 也很難被注意到。所以,隱性的磁盤I/O操作,更需要格外關(guān)注。要解決上面的問題,有三種策略:使用非阻塞I/O,對(duì)文件進(jìn)行異步讀寫操作。業(yè)務(wù)層面封裝一個(gè)異步的I/O操作,最簡(jiǎn)單的策略就是由一個(gè)獨(dú)

16、立的線程或者線程池來(lái) 執(zhí)行磁盤I/O操作。選擇支持非阻塞方式調(diào)用的I/O類庫(kù),例如使用10g4j的異步日志API。以JDK1.7為例,它提供了異步的文件I/O操作類庫(kù),基于該類庫(kù),就不需要擔(dān)心磁盤I/O操作被阻塞:13 O AsyrchironouFiieChanrelQrchroncusfileChsrinel()t? extendiE 0PnCptinn,Ew#cutorS*rviii:e. FtaAttfibut*?*.) Atynrhr-roj;7l?Chin-eli?F NO_ATRIBUTES FihAlliiLute)白三:void lockfA. CofTipletidtiIH

17、andlisrcFieLodc, ? super 4河、工於;ruic.A liQcktlEin long, boo If sin) ri tjr=-= Hi If nri F lockO : Future rilcLiKk tryiockOongL long, boolean)卜ilci ork卜 tryLockCftj31 irppid(ByteBirffer long. X CnmpleiorHandler 1一小p e口d Bytf B u代匕 159)f- tuq-w/rkelByteBuffer fongp Ap CorfiplwicnHaHdler)-2-3 JDK1.7 異步非

18、阻塞文件接口臼己在上層封裝異步 I/O操作,也比較簡(jiǎn)單,它的優(yōu)點(diǎn)是可以實(shí)現(xiàn)磁盤I/O操作與微服務(wù)之間的線程隔離,但是底層仍然使用的是同步阻塞I/O ,如果此時(shí)磁盤的I/O比較高,依然會(huì)阻塞寫磁盤的I/O線程。它的原理如下所示:將文件I/O操作封裝成一個(gè) Task或者Event ,投遞到文件I/O線程池的消息隊(duì)列中,14根據(jù)投遞結(jié)果,構(gòu)造I/O操作相關(guān)聯(lián)的Future對(duì)象給微服務(wù)調(diào)用線程。通過向 Future對(duì) 象注冊(cè)Listener并實(shí)現(xiàn)callback接口,可以實(shí)現(xiàn)異步回調(diào)通知,這樣微服務(wù)和文件 I/O操 作就實(shí)現(xiàn)了線程隔離。文件 I/O操作耗時(shí),并不會(huì)阻塞微服務(wù)調(diào)度線程。當(dāng)使用第三方文件I

19、/O操作類庫(kù)時(shí),需要注意下相關(guān)API ,盡量使用支持異步非阻塞接 口的API,如果沒有,則需要考慮是否做上層的異步封裝。 數(shù)據(jù)庫(kù)操作部分?jǐn)?shù)據(jù)庫(kù)訪問支持非阻塞方式,例如 Oracle的OCI ,它支持non-blocking 模式和 blocking 模式:阻塞方式就是當(dāng)調(diào)用OCI操作時(shí),必須等到此 OCI操作完成后服務(wù)器才返回客戶端相應(yīng)的信息,不管是成功還是失敗。非阻塞方式是當(dāng)客戶端提交OCI操作給服務(wù)器后,服務(wù)器立即返回OCI_STILL_EXECUTING 信息,而并不等待服務(wù)端的操作完成。對(duì)于 non-blocking 方式,應(yīng)用程序若收到一個(gè) OCI函數(shù)的返回值為 OCI_STILL_

20、EXECUTING 時(shí)必須再次對(duì)每一個(gè) OCI函數(shù)的返回值進(jìn)行判斷,判斷其成功與 否??赏ㄟ^設(shè)置服務(wù)器屬性為OCI_ATTR_NONBLOCKING_MODE來(lái)實(shí)現(xiàn)。對(duì)于Java語(yǔ)言而言,由于JDK本身提供了數(shù)據(jù)庫(kù)連接驅(qū)動(dòng)相關(guān)的接口定義,JDBC驅(qū)動(dòng)本身就是同步 API接口,因此,Java語(yǔ)言的開源 ORM 框架也都是同步阻塞的,例如 MyBatis、Hibernate 等。盡管大部分?jǐn)?shù)據(jù)庫(kù)訪問接口是同步阻塞的,但是由于數(shù)據(jù)庫(kù)中間件的超時(shí)控制機(jī)制都 比較成熟,因此通過合理設(shè)置超時(shí)時(shí)間,可以避免微服務(wù)的數(shù)據(jù)庫(kù)訪問被長(zhǎng)時(shí)間掛住。也可以在應(yīng)用上層封裝異步數(shù)據(jù)庫(kù)操作層,實(shí)現(xiàn)微服務(wù)調(diào)度與數(shù)據(jù)庫(kù)操作的線程

21、級(jí)隔 離,原理2.2章節(jié)已經(jīng)介紹過,采用該方式同樣存在兩點(diǎn)不足:排隊(duì)現(xiàn)象:如果某個(gè)數(shù)據(jù)庫(kù)操作非常耗時(shí),超時(shí)時(shí)間配置的又比較大(例如 30S),會(huì)導(dǎo)致后續(xù)的數(shù)據(jù)庫(kù)操作在隊(duì)列中排隊(duì)。15所以不能高效發(fā)無(wú)法充分發(fā)揮數(shù)據(jù)庫(kù)效能:由于底層數(shù)據(jù)庫(kù)訪問采用同步阻塞的方式,揮數(shù)據(jù)庫(kù)的效能。故障隔離由于大部分微服務(wù)采用同步接口調(diào)用,而且多個(gè)領(lǐng)域相關(guān)的微服務(wù)會(huì)部署在同一個(gè)進(jìn)程中,很容易發(fā)生“雪崩效應(yīng)”,即某個(gè)微服務(wù)提供者故障,導(dǎo)致調(diào)用該微服務(wù)的消費(fèi)者、或 者與故障微服務(wù)合設(shè)在同一個(gè)進(jìn)程中的其它微服務(wù)發(fā)生級(jí)聯(lián)故障,最終導(dǎo)致系統(tǒng)崩潰。為了避免“雪崩效應(yīng)”的發(fā)生,需要支持多種維度的依賴和故障隔離,以實(shí)現(xiàn)微服務(wù)的HA。通

22、信鏈路隔離由于網(wǎng)絡(luò)通信本身通常不是系統(tǒng)的瓶頸,因此大部分服務(wù)框架會(huì)采用多線程 +單個(gè)通信+單鏈路的方式進(jìn)行通信正如前面章節(jié)所述,由于微服務(wù)使用異步非阻塞通信,單個(gè) I/O線程可以同時(shí)并發(fā)處理多個(gè)鏈路的消息,而且網(wǎng)絡(luò)讀寫都是非阻塞的,因此采用多線程16性能本身問題不大。但是從可靠性角度來(lái)看,只支持單鏈路本身又存在一些可靠性隱患, 們從下面的案例中看下問題所在。某互聯(lián)網(wǎng)基地微服務(wù)架構(gòu)上線之后,發(fā)現(xiàn)在一些時(shí)段,經(jīng)常有業(yè)務(wù)超時(shí),超時(shí)的業(yè)務(wù)沒有固定規(guī)律。經(jīng)定位發(fā)現(xiàn)當(dāng)有較多的批量?jī)?nèi)容同步、語(yǔ)音和視頻類微服務(wù)調(diào)用時(shí),系統(tǒng)的整體時(shí)延就增高了很多, 而且存在較突出的時(shí)延毛刺。由于這些操作獲取的消息碼流往往達(dá)到數(shù)

23、M到數(shù)十兆,微服務(wù)之間又采用單鏈路的方式進(jìn)行P2P通信,導(dǎo)致大碼流的傳輸影響了其它消息的讀寫效率,增大了微服務(wù)的響應(yīng)時(shí)延。問題定位出來(lái)之后,對(duì)微服務(wù)之間的通信機(jī)制做了優(yōu)化,節(jié)點(diǎn)之間支持配置多鏈路,每個(gè)鏈路之間還可以實(shí)現(xiàn)不同策略的隔離,例如根據(jù)消息碼流大小、根據(jù)微服務(wù)的優(yōu)先級(jí)等 策略,實(shí)現(xiàn)鏈路級(jí)的隔離,優(yōu)化之后的微服務(wù)通信機(jī)制:圖3-2支持多鏈路隔離17調(diào)度資源隔離微服務(wù)之間隔離當(dāng)多個(gè)微服務(wù)合設(shè)運(yùn)行在同一個(gè)進(jìn)程內(nèi)部時(shí),可以利用線程實(shí)現(xiàn)不同微服務(wù)之間的隔離。對(duì)于核心微服務(wù),發(fā)布的時(shí)候可以獨(dú)占一個(gè)線程/線程池,對(duì)于非核心微服務(wù),則可以共享同一個(gè)大的線程池,在實(shí)現(xiàn)微服務(wù)隔離的同時(shí),避免線程過于膨脹:消

24、費(fèi)者非核心服務(wù)mE核心用艮務(wù)2淺程池1核心服務(wù)1線程池2核心服務(wù)2淺程池3圖3-3微服務(wù)之間故障隔離假如非核心服務(wù) 3發(fā)生故障,長(zhǎng)時(shí)間阻塞線程池1的工作線程,其它與其共用線程池消息隊(duì)列的非核心服務(wù) 1和服務(wù)2只能在隊(duì)列中排隊(duì)等待,當(dāng)服務(wù)3釋放線程之后,排隊(duì)的服務(wù)1和服務(wù)2可能已經(jīng)超時(shí),只能被丟棄掉,導(dǎo)致業(yè)務(wù)處理失敗。采用線程池隔離的核心服務(wù) 1和服務(wù)2,由于各自獨(dú)占線程池,擁有獨(dú)立的消息隊(duì)列,它的執(zhí)行不受發(fā)生故障的非核心服務(wù)1影響,因此可以繼續(xù)正常工作。通過獨(dú)立線程池部署核心服務(wù),可以防止故障擴(kuò)散,保障核心服務(wù)的正常運(yùn)行。18第三方依賴隔離在微服務(wù)中通常會(huì)調(diào)用第三方中間件服務(wù),例如分布式緩存服

25、務(wù)、分布式消息隊(duì)列、 NoSQL服務(wù)等。只要調(diào)用第三方服務(wù),就會(huì)涉及跨網(wǎng)絡(luò)操作,由于客戶端SDK API的封裝, 很多故障都是隱性的,因此,它的可靠性需要額外關(guān)注。整體而言,第三方依賴隔離可以采用線程池+響應(yīng)式編程(例如 RxJava )的方式實(shí)現(xiàn),它的原理如下所示:1)對(duì)第三方依賴進(jìn)行分類,每種依賴對(duì)應(yīng)一個(gè)獨(dú)立的線程/線程池。2)微服務(wù)不直接調(diào)用第三方依賴的API ,而是使用異步封裝之后的API接口。3)異步調(diào)用第三方依賴 API之后,獲取Future對(duì)象。利用響應(yīng)式編程框架,可以訂閱后續(xù)的事件,接收響應(yīng),針對(duì)響應(yīng)進(jìn)行編程。利用Netflix開源的hystrix + RxJava ,可以快速

26、實(shí)現(xiàn)第三方依賴的隔離,后續(xù)章節(jié)我 們會(huì)詳細(xì)介紹下如何使用。進(jìn)程級(jí)隔離對(duì)于核心的微服務(wù),例如商品購(gòu)買、用戶注冊(cè)、計(jì)費(fèi)等,可以采用獨(dú)立部署的方式,實(shí) 現(xiàn)高可用性。容器隔離微服務(wù)鼓勵(lì)軟件開發(fā)者將整個(gè)軟件解耦為功能單一的服務(wù),并且這些服務(wù)能夠獨(dú)立部署、升級(jí)和擴(kuò)容。如果微服務(wù)抽象的足夠好,那么微服務(wù)的這一優(yōu)點(diǎn)將能夠提升應(yīng)用的敏捷性和 自治理能力。利用Docker容器部署微服務(wù),可以帶來(lái)如下幾個(gè)優(yōu)點(diǎn):19高效:Docker容器的啟動(dòng)和停止不需要幾分鐘,只要幾百毫秒就足夠了。使用Docker部署微服務(wù),微服務(wù)的啟動(dòng)和銷毀速度非???,在高壓力時(shí),可以實(shí)現(xiàn)秒級(jí)彈性伸縮。高性能:Docker容器的性能接近裸的物理

27、機(jī),比VM平均高20%+ 。隔離性:利用Docker ,可以實(shí)現(xiàn)0.1 core的隔離?;诩?xì)粒度的資源隔離機(jī)制,可以實(shí)現(xiàn)高密度的部署微服務(wù),同時(shí)實(shí)現(xiàn)它們之間的資源層隔離,保障微服務(wù)的可靠性??梢浦残裕涸诨谔摂M機(jī)的解決方案中,應(yīng)用的可移植性通常來(lái)說會(huì)受到云提供商所提供的虛擬機(jī)格式限制。 如果應(yīng)用程序需要部署到不同類型的虛擬機(jī)中,需要針對(duì)特定的虛擬機(jī)格式做鏡像文件,新增很多額外的開發(fā)和測(cè)試工作量。Docker容器的設(shè)計(jì)理念是“一次編寫,到處運(yùn)行”,這可以使開發(fā)者避免上面這種限制?;贒ocker容器部署微服務(wù),實(shí)現(xiàn)物理資源層隔離示意圖如下所示:MS3基于Docker容器的微服務(wù)隔離圖3-4L

28、* -VM隔離除了 Docker容器隔離,也可以使用VM對(duì)微服務(wù)進(jìn)行故障隔離,相比于Docker容器,使用VM進(jìn)行微服務(wù)隔離存在如下優(yōu)勢(shì):.微服務(wù)的資源隔離性更好,CPU、內(nèi)存、網(wǎng)絡(luò)等可以實(shí)現(xiàn)完全的資源隔離。.對(duì)于已經(jīng)完成硬件虛擬化的遺留系統(tǒng),可以直接使用已有的 VM ,而不需要在 VM中重新部署Docker容器。20集群容錯(cuò)當(dāng)微服務(wù)不可用時(shí),需要根據(jù)預(yù)置的策略做容錯(cuò)處理,大部分的容錯(cuò)能力和策略是公共的,因此可以下沉到服務(wù)框架中實(shí)現(xiàn)。路由容錯(cuò)當(dāng)集群環(huán)境中微服務(wù)調(diào)用失敗之后,利用路由容錯(cuò)機(jī)制,可以在底層實(shí)現(xiàn)微服務(wù)的自動(dòng)容錯(cuò)處理,提升系統(tǒng)的可靠性。常用的容錯(cuò)策略包括:失敗自動(dòng)切換機(jī)制:微服務(wù)調(diào)用失

29、敗自動(dòng)切換策略指的是當(dāng)發(fā)生服務(wù)調(diào)用異常時(shí),重新選路,查找下一個(gè)可用的微服務(wù)提供者。微服務(wù)發(fā)布的時(shí)候, 可以指定服務(wù)的集群容錯(cuò)策略。消費(fèi)者可以覆蓋服務(wù)提供者的通用配置,實(shí)現(xiàn)個(gè)性化的容錯(cuò)策略。失敗回調(diào)機(jī)制:微服務(wù)調(diào)用失敗之后, 提供異常回調(diào)接口, 執(zhí)行微服務(wù)消費(fèi)者自定義的失敗處理邏輯。快速失敗機(jī)制:在業(yè)務(wù)高峰期,對(duì)于一些非核心的服務(wù),希望只調(diào)用一次,失敗也不再重試,為重要的核心服務(wù)節(jié)約寶貴的運(yùn)行資源。此時(shí),快速失敗是個(gè)不錯(cuò)的選擇??焖偈〔呗缘脑O(shè)計(jì)比較簡(jiǎn)單,獲取到服務(wù)調(diào)用異常之后,直接忽略異常,記錄異常日志。服務(wù)降級(jí)大促或者業(yè)務(wù)高峰時(shí),為了保證核心服務(wù)的 SLA ,往往需要停掉一些不太重要的業(yè)務(wù),

30、例如商品評(píng)論、論壇或者粉絲積分等。另外一種場(chǎng)景就是某些服務(wù)因?yàn)槟撤N原因不可用,但是流程不能直接失敗,需要本地Mock服務(wù)端實(shí)現(xiàn),做流程放通。 以圖書閱讀為例,如果用戶登錄余額鑒權(quán)服務(wù)不能正常工作,需要做業(yè)務(wù)放通,記錄消費(fèi)話單,允許用戶繼續(xù)閱讀,而不是返回失敗。21通過服務(wù)治理的服務(wù)降級(jí)功能,即可以滿足上述兩種場(chǎng)景的需求。強(qiáng)制降級(jí)當(dāng)外界的觸發(fā)條件達(dá)到某個(gè)臨界值時(shí),由運(yùn)維人員/開發(fā)人員決策,對(duì)某類或者某個(gè)服務(wù)進(jìn)行強(qiáng)制降級(jí)。強(qiáng)制降級(jí)的常用策略:不發(fā)起遠(yuǎn)程服務(wù)調(diào)用,直接返回空。例如 mock = force: return null 。不發(fā)起遠(yuǎn)程服務(wù)調(diào)用,直接拋出指定異常。例如 mock = forc

31、e: throw Exception 。不發(fā)起遠(yuǎn)程服務(wù)調(diào)用,直接執(zhí)彳T本地模擬接口實(shí)現(xiàn)類。mock = force: execute Bean: 。容錯(cuò)降級(jí)當(dāng)非核心服務(wù)不可用時(shí),可以對(duì)故障服務(wù)做業(yè)務(wù)邏輯放通,以保障核心服務(wù)的運(yùn)行。容錯(cuò)降級(jí)與屏蔽降級(jí)的主要差異是:.觸發(fā)條件不同:容錯(cuò)講解是根據(jù)服務(wù)調(diào)用結(jié)果,自動(dòng)匹配觸發(fā)的;而屏蔽降級(jí)往往是通過人工根據(jù)系統(tǒng)運(yùn)行情況手工操作觸發(fā)的。.作用不同:容錯(cuò)降級(jí)是當(dāng)服務(wù)提供者不可用時(shí),讓消費(fèi)者執(zhí)行業(yè)務(wù)放通;屏蔽降級(jí)的主要目的是將原屬于降級(jí)業(yè)務(wù)的資源調(diào)配出來(lái)供核心業(yè)務(wù)使用。.調(diào)用機(jī)制不同:一個(gè)發(fā)起遠(yuǎn)程服務(wù)調(diào)用,一個(gè)只做本地調(diào)用。容錯(cuò)降級(jí)的常用策略如下:異常轉(zhuǎn)義:

32、 mock = fail: throw Exception22o將異常屏蔽掉,直接自定義降級(jí)邏輯:mock = fail: execute Bean: 執(zhí)行本地模擬接口實(shí)現(xiàn)類,返回Mock接口的執(zhí)行結(jié)果。服務(wù)降級(jí)Portal利用服務(wù)治理 Portal ,可以在線的動(dòng)態(tài)修改微服務(wù)的降級(jí)策略,實(shí)時(shí)生效,它的界面如下所示:圖4-1服務(wù)降級(jí)配置界面熔斷機(jī)制熔斷機(jī)制(Circuit Breaker ),也叫自動(dòng)停盤機(jī)制,是指當(dāng)股指波幅達(dá)到規(guī)定的熔斷點(diǎn) 時(shí),交易所為控制風(fēng)險(xiǎn)采取的暫停交易措施。在微服務(wù)領(lǐng)域,熔斷機(jī)制是從消費(fèi)端保護(hù)微服務(wù)提供者的措施,當(dāng)微服務(wù)的運(yùn)行質(zhì)量低于某個(gè)臨界值時(shí),啟動(dòng)熔斷機(jī)制,暫停微服

33、務(wù)調(diào)用一段時(shí)間, 以保障后端的微服務(wù)不會(huì)因?yàn)?持續(xù)過負(fù)荷而宕機(jī)。23工作原理微服務(wù)的熔斷機(jī)制原理如下所示:.微服務(wù)調(diào)用時(shí),對(duì)熔斷開關(guān)狀態(tài)進(jìn)行判斷,當(dāng)熔斷器開關(guān)關(guān)閉時(shí),請(qǐng)求被允許通過熔斷器。如果當(dāng)前微服務(wù)健康度高于指定閾值,開關(guān)繼續(xù)保持關(guān)閉。否則開關(guān)切換為打開狀O.當(dāng)熔斷器開關(guān)打開時(shí), 微服務(wù)調(diào)用請(qǐng)求被禁止通過。調(diào)用失敗,執(zhí)行本地降級(jí)邏輯,如果沒有實(shí)現(xiàn)降級(jí)邏輯,默認(rèn)返回異常。.當(dāng)熔斷器開關(guān)處于打開狀態(tài)時(shí),經(jīng)過指定周期 T,熔斷器會(huì)自動(dòng)進(jìn)入半開狀態(tài) ,這時(shí)熔斷器會(huì)允許請(qǐng)求通過,當(dāng)請(qǐng)求調(diào)用成功時(shí),熔斷器恢復(fù)到關(guān)閉狀態(tài)。若失敗 ,則繼續(xù)保持打開狀態(tài)。它的工作原理示意如下:道服務(wù)調(diào)用本地降級(jí)接口遠(yuǎn)程被服

34、務(wù)謂用圖4-2微服務(wù)熔斷器工作原理熔斷器機(jī)制能保證微服務(wù)消費(fèi)者在微服務(wù)運(yùn)行狀態(tài)不佳時(shí),快速返回結(jié)果,避免大量的同步等待。并且能在指定周期T后繼續(xù)偵測(cè)微服務(wù)是否可用,以實(shí)現(xiàn)故障恢復(fù)之后的自動(dòng)感24知。微服務(wù)健康度熔斷器開關(guān)的狀態(tài)取決于微服務(wù)的運(yùn)行質(zhì)量,微服務(wù)的運(yùn)行質(zhì)量通常由多種因素決定,具有多個(gè)衡量因子。通過對(duì)微服務(wù)健康度建模,可以實(shí)現(xiàn)對(duì)微服務(wù)運(yùn)行質(zhì)量的360 0實(shí)時(shí)評(píng)估。微服務(wù)健康度模型如下所示:亡PE使用章內(nèi)存性用零 網(wǎng)絡(luò):國(guó) 碓骰IA3基砒曼源KPIlKPI服答詞用口”o-脫驗(yàn)調(diào)用正為同鬼L臟女訊/或約毒微服務(wù)健康度浪捶惕至降級(jí)-重要事件士警-堂意吉塞二一由總告整 一附吉誓圖4-3微服務(wù)健

35、康度模型微服務(wù)運(yùn)維體系通過分布式日志采集系統(tǒng)、告警系統(tǒng)、性能KPI數(shù)據(jù)采集等,利用在線大數(shù)據(jù)實(shí)時(shí)分析技術(shù), 通過健康度模型,對(duì)微服務(wù)的健康度按照周期進(jìn)行實(shí)時(shí)打分,同時(shí)將微服務(wù)的得分通過消息隊(duì)列訂閱發(fā)布出去,各個(gè)節(jié)點(diǎn)訂閱微服務(wù)的健康度得分,與熔斷器閾值進(jìn)行比較,修改熔斷器開關(guān)的狀態(tài)。流量控制當(dāng)資源成為瓶頸時(shí), 服務(wù)框架需要對(duì)消費(fèi)者做限流,啟動(dòng)流控保護(hù)機(jī)制。 流量控制有多種策略,比較常用的有:針對(duì)訪問速率的靜態(tài)流控、針對(duì)資源占用的動(dòng)態(tài)流控等。在實(shí)踐中,各種流量控制策略需要綜合使用才能起到較好的效果。25動(dòng)態(tài)流控動(dòng)態(tài)流控的最終目標(biāo)是為了保命,并不是對(duì)流量或者訪問速度做精確控制。當(dāng)系統(tǒng)負(fù) 載壓力非常大

36、時(shí),系統(tǒng)進(jìn)入過負(fù)載狀態(tài),可能是 CPU、內(nèi)存資源已經(jīng)過載,也可能是應(yīng)用 進(jìn)程內(nèi)部的資源幾乎耗盡,如果繼續(xù)全量處理業(yè)務(wù), 可能會(huì)導(dǎo)致消息嚴(yán)重積壓或者應(yīng)用進(jìn)程宕機(jī)。動(dòng)態(tài)流控檢測(cè)的資源包括:CPU使用率。內(nèi)存使用率(對(duì)于 Java ,主要是JVM內(nèi)存使用率)。隊(duì)列積壓率。主機(jī)CPU、內(nèi)存使用率采集算法非常多,例如使用 java.lang.Process 執(zhí)行top、sar 等外部命令獲取系統(tǒng)資源使用情況,然后解析后計(jì)算獲得資源使用率。也可以直接讀取操作系統(tǒng)的系統(tǒng)文件獲取相關(guān)數(shù)據(jù),需要注意的是,無(wú)論是執(zhí)行操作系統(tǒng)的本地命令,還是直接讀取操作系統(tǒng)的資源使用率文件,都是操作系統(tǒng)本地相關(guān)的,不同的操作系統(tǒng)和

37、服務(wù)器,命令和輸出格式可能存在很大差異。在計(jì)算時(shí)需要首先判斷操作系統(tǒng)類型,然后調(diào)用相關(guān)操作系統(tǒng)的資源采集接口實(shí)現(xiàn)類,通過這種方式就可以支持跨平臺(tái)。動(dòng)態(tài)流控是分級(jí)別的,不同級(jí)別拒掉的消息比例不同,這取決于資源的負(fù)載使用情況。例如當(dāng)發(fā)生一級(jí)流控時(shí),拒絕掉1/4的消息;發(fā)生二級(jí)流控時(shí),拒絕掉 1/2消息;發(fā)生三級(jí)流控時(shí),所有的消息都被流控掉。不同的級(jí)別有不同的流控閾值, 系統(tǒng)上線后會(huì)提供默認(rèn)的; 流控閾值,不同流控因子的 流控閾值不同,業(yè)務(wù)上線之后通常會(huì)根據(jù)現(xiàn)場(chǎng)的實(shí)際情況做閾值調(diào)優(yōu),因此流控閾值需要支持在線修改和動(dòng)態(tài)生效。26需要指出的是為了防止系統(tǒng)波動(dòng)導(dǎo)致的偶發(fā)性流控,無(wú)論是進(jìn)入流控狀態(tài)還是從流控

38、狀態(tài)恢復(fù),都需要連續(xù)采集 N次并計(jì)算平均值,如果連續(xù) N次平均值大于流控閾值,則進(jìn)入 流控狀態(tài);同理,只有連續(xù)N次資源使用率平均值低于流控閾值, 才能脫離流控恢復(fù)正常。 靜態(tài)流控靜態(tài)流控主要針對(duì)客戶端訪問速率進(jìn)行控制,它通常根據(jù)服務(wù)質(zhì)量等級(jí)協(xié)定(SLA)中約定的QPS做全局流量控制,例如計(jì)費(fèi)服務(wù)的靜態(tài)流控閾值為200 QPS ,則無(wú)論集群有多少個(gè)計(jì)費(fèi)服務(wù)實(shí)例,它們總的處理速率之和不能超過200 QPS 。由于微服務(wù)具備彈性伸縮、動(dòng)態(tài)上線和下線等特性,因此集群中某個(gè)微服務(wù)實(shí)例的節(jié)點(diǎn)個(gè)數(shù)是動(dòng)態(tài)變化的,采用傳統(tǒng)的平均分配制無(wú)法做到精準(zhǔn)的控制。在實(shí)踐中,比較成熟的集群靜態(tài)流控策略是動(dòng)態(tài)配額申請(qǐng)制,它的工作原理如下:.系統(tǒng)部署的時(shí)候,根據(jù)微服務(wù)節(jié)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論