不可否認(rèn)甚牲,在過(guò)去幾年中璃弄,像Docker和Kubernetes這樣的技術(shù),徹底改變了我們對(duì)軟件開發(fā)和部署的方式窜觉。
盡管軟件開發(fā)行業(yè)的快節(jié)奏推動(dòng)開發(fā)人員使用新技術(shù),但是重要的是我們須要退一步思考并理解這些技術(shù)的背后原理及模式北专。
斷路器模式就是在微服務(wù)架構(gòu)中廣泛采用的模式之一禀挫。 我們將比較實(shí)現(xiàn)它的兩種不同方法的優(yōu)缺點(diǎn):Hystrix和Istio。
微服務(wù)同步通信的核心問(wèn)題
假設(shè)有一個(gè)非常簡(jiǎn)單的微服務(wù)架構(gòu)拓颓,包括: 1.后端服務(wù) 2.前端服務(wù)(注:可以理解成是微服務(wù)A,B兩個(gè)服務(wù)语婴,A調(diào)用B服務(wù),這里的前端服務(wù)就是A)
我們假設(shè)后端和前端通過(guò)同步HTTP調(diào)用進(jìn)行通信驶睦。
客戶端C1和C2調(diào)用前端來(lái)獲取一些信息砰左。由于前端沒(méi)有所有必需的數(shù)據(jù),因此它會(huì)調(diào)用后端來(lái)獲取缺失的數(shù)據(jù)场航。
但是由于網(wǎng)絡(luò)通信會(huì)產(chǎn)生很多問(wèn)題:
前后端的網(wǎng)絡(luò)故障
后端由某個(gè)bug導(dǎo)致服務(wù)掛了
后端依賴的服務(wù)(例如數(shù)據(jù)庫(kù))掛了
根據(jù)墨菲定律(“任何可能出錯(cuò)的東西都會(huì)出錯(cuò)”)缠导,前端和后端之間的通信早晚會(huì)遇到失敗的。
如果我們從單個(gè)請(qǐng)求從前端到后端的生命周期來(lái)看溉痢,后端服務(wù)會(huì)由于各種各樣的原因?qū)е虏豢捎闷г欤谀承r(shí)候,前端服務(wù)調(diào)用會(huì)由于超時(shí)而取消孩饼。
縮小到應(yīng)用程序級(jí)別髓削,多個(gè)客戶端同時(shí)調(diào)用前端服務(wù),這實(shí)際變成了對(duì)后端服務(wù)的多次調(diào)用:前端服務(wù)的很多請(qǐng)求將處于超時(shí)狀態(tài)镀娶。
在這種情況下唯一合理的解決方案是快速失斄⑻拧:應(yīng)該讓前端服務(wù)知道后端服務(wù)出現(xiàn)問(wèn)題,并立即將故障返回給自己的客戶端汽畴。
斷路器模式
在電路領(lǐng)域中旧巾,斷路器是設(shè)計(jì)用于保護(hù)電路的自動(dòng)操作的電氣開關(guān)耸序。 其基本功能是在檢測(cè)到故障后中斷電流。 然后可以在故障解決后重置(手動(dòng)或自動(dòng))以恢復(fù)正常操作鲁猩。
這和我們的問(wèn)題非常的類似:為了保護(hù)我們的應(yīng)用程序免受過(guò)多的請(qǐng)求坎怪,最好在后端檢測(cè)到故障時(shí)立即中斷前端和后端之間的通信。
在他已發(fā)布的書中廓握,邁克爾·尼加德使用了這個(gè)類比搅窿,并提出了應(yīng)用于上述超時(shí)問(wèn)題的設(shè)計(jì)模式。 它背后的流程非常簡(jiǎn)單:
如果調(diào)用失敗隙券,將失敗值的增加1
如果調(diào)用失敗的次數(shù)超過(guò)某個(gè)閾值男应,就打開電路
如果電路處于打開狀態(tài),則立即返回錯(cuò)誤信息或返回一個(gè)默認(rèn)值
如果電路處于打開狀態(tài)且已經(jīng)過(guò)了一段時(shí)間娱仔,則半開電路
如果電路半開沐飘,下一次請(qǐng)求調(diào)次失敗,請(qǐng)?jiān)俅未蜷_
如果電路半開牲迫,下一次請(qǐng)求調(diào)用成功耐朴,請(qǐng)將其關(guān)閉
我們可以用下圖來(lái)進(jìn)行總結(jié):
Istio斷路器
Istio是服務(wù)網(wǎng)格,是微服務(wù)應(yīng)用程序的可配置基礎(chǔ)設(shè)施層盹憎。 它使服務(wù)實(shí)例之間的通信變得靈活筛峭,可靠和快速,并提供服務(wù)發(fā)現(xiàn)陪每,負(fù)載平衡影晓,加密,身份驗(yàn)證和授權(quán)檩禾,對(duì)斷路器模式的支持以及其他功能挂签。
Istio是在底層集群管理平臺(tái)上提供了一個(gè)抽象層,例如Kubernetes锌订,Mesos等竹握,并且需要以這種方式管理您的應(yīng)用程序画株。
其核心辆飘,Istio使用(sidecar container pattern)集裝箱模式并位于應(yīng)用程序?qū)嵗懊娴腅nvoy代理實(shí)例,以及管理它們的工具Pilot谓传。這種代理策略有許多優(yōu)點(diǎn):
- HTTP蜈项,gRPC,WebSocket和TCP流量的自動(dòng)負(fù)載均衡续挟。 2.通過(guò)豐富的路由規(guī)則紧卒,重試,故障轉(zhuǎn)移和故障注入诗祸,對(duì)流量行為進(jìn)行細(xì)粒度控制跑芳。 3.可插入的策略層和配置API轴总,支持訪問(wèn)控制,速率限制和配額博个。 4.集群中所有流量的自動(dòng)度量(metrics)怀樟,日志和跟蹤,包括群集入口和出口盆佣。 5. 基于強(qiáng)大的身份的身份驗(yàn)證和授權(quán)往堡,在集群中實(shí)現(xiàn)服務(wù)到服務(wù)安全的通信。
由于后端的出站調(diào)用是通過(guò)Envoy代理共耍,因此很容易檢測(cè)到它們何時(shí)超時(shí)虑灰。然后代理可以攔截進(jìn)一步的調(diào)用并立即返回,有效地快速失敗痹兜。特別是穆咐,這使得斷路器圖能夠以黑盒方式操作。
配置Istio斷路器
正如我們所說(shuō)字旭,Istio在您選擇的集群管理平臺(tái)上構(gòu)建庸娱,并且需要通過(guò)它來(lái)部署您的應(yīng)用程序。 Kubernetes通過(guò)DestinationRule實(shí)現(xiàn)斷路器模式谐算,更確切的路徑就是TrafficPolicy(以前叫circuitBreaker) - > OutlierDetection熟尉,模型如下:
參數(shù)如下:
Parameters are as follows:
Field ? ??? ?? Description
consecutiveErrors 當(dāng)斷路器開起的時(shí)候,返回5XX的錯(cuò)誤碼
interval 斷路器檢查分析(check analysis)之間的時(shí)間間隔洲脂。
baseEjectionTime 最短開放時(shí)間
maxEjectionPercent Maximum % of hosts in the load balancing pool for the upstream service that can be ejected.
與前面講的斷路器相比斤儿,有兩個(gè)主要差異:
半開狀態(tài)是不存在的。但是恐锦,斷路器保持打開的持續(xù)時(shí)間取決于被調(diào)服務(wù)之前失敗的次數(shù)往果。不斷失效的服務(wù)將導(dǎo)致斷路器的打開持續(xù)時(shí)間越來(lái)越長(zhǎng)。
在基礎(chǔ)模式中一铅,有一個(gè)叫做應(yīng)用程序(后端)陕贮。在現(xiàn)實(shí)的生產(chǎn)環(huán)境中,可能會(huì)在負(fù)載均衡器后面部署同一應(yīng)用程序的多個(gè)實(shí)例潘飘。有些實(shí)例可能會(huì)失敗肮之,有些可能會(huì)正常工作,而且由于Istio也扮演了負(fù)載平衡器的角色卜录,它能夠跟蹤失敗的實(shí)例并將它們從負(fù)載均衡池中彈出戈擒,在某種程度上說(shuō):maxEjectionPercent attribute作是保留一部分實(shí)例在池中。
Istio斷路器更像是一個(gè)黑盒子艰毒。它需要一個(gè)高視角筐高,并且只能在出現(xiàn)問(wèn)題時(shí)打開電路。另一方面,它設(shè)置起來(lái)非常簡(jiǎn)單柑土,并且不需要任何底層代碼知識(shí)蜀肘,并且可以將其配置為事后想法。
Hystrix斷路器
Hystrix是一個(gè)最初由Netflix提供的開源Java庫(kù)稽屏。 它是一個(gè)延遲幌缝、容錯(cuò)庫(kù),旨在隔離對(duì)遠(yuǎn)程系統(tǒng)诫欠,服務(wù)和第三方庫(kù)的訪問(wèn)時(shí)涵卵,避免級(jí)聯(lián)故障,并在復(fù)雜的分布式系統(tǒng)中實(shí)現(xiàn)彈性荒叼,因?yàn)樵谶@些系統(tǒng)中轿偎,故障是不可避免的。
Hystrix有許多功能被廓,包括: 通過(guò)第三方客戶端庫(kù)訪問(wèn)(通常通過(guò)網(wǎng)絡(luò))訪問(wèn)的依賴項(xiàng)坏晦,防止延遲和故障。 防止復(fù)雜分布式系統(tǒng)中的級(jí)聯(lián)故障嫁乘。 快速失敗并迅速恢復(fù)昆婿。 在可能的情況下,實(shí)施優(yōu)雅地降級(jí)蜓斧。 實(shí)現(xiàn)近實(shí)時(shí)監(jiān)控仓蛆,報(bào)警和操作控制。 當(dāng)然挎春,斷路器模式在這些功能中占有一席之地看疙。 因?yàn)镠ystrix是一個(gè)庫(kù),它以白盒方式實(shí)現(xiàn)它直奋。
注意:
Resilience4J Netflix最近宣布已停止開發(fā)Hystrix庫(kù)能庆,轉(zhuǎn)而采用不太知名的Resilience4J項(xiàng)目。 盡管客戶端代碼可能有點(diǎn)不同脚线,但Hystrix和Resilience4J之間的方法是類似的搁胆。
Hystrix斷路器例子
考慮電子商務(wù)Web應(yīng)用程序的情況。 該應(yīng)用程序由不同的微服務(wù)構(gòu)成邮绿,每個(gè)服務(wù)都基于業(yè)務(wù)功能劃分: 認(rèn)證 目錄瀏覽 購(gòu)物車管理 定價(jià)和報(bào)價(jià) 等等渠旁。
當(dāng)顯示目錄的時(shí)候,將通過(guò)定價(jià)和報(bào)價(jià)服務(wù)查詢其定價(jià)/報(bào)價(jià)斯碌。如果這個(gè)服務(wù)掛掉了一死,他將不會(huì)返回任務(wù)價(jià)格回來(lái),就會(huì)導(dǎo)致無(wú)法購(gòu)買任何東西傻唾。
從商業(yè)角度來(lái)看,宕機(jī)不僅會(huì)對(duì)品牌的感知產(chǎn)生影響,還會(huì)降低銷售額冠骄。 盡管價(jià)格并不完全正確伪煤,但大多數(shù)銷售策略仍傾向于出售。 實(shí)現(xiàn)此銷售策略的解決方案是:在服務(wù)不可用的時(shí)候可以返回緩存里的價(jià)格凛辣。
Hystrix提供了一種斷路器實(shí)現(xiàn):允許在電路打開時(shí)進(jìn)行降級(jí)抱既。
這是Hystrix模型的簡(jiǎn)化類圖:
最核心的地方發(fā)生在HystrixCommand的 run()和getFallback()方法中: run()是實(shí)際代碼,例如 從報(bào)價(jià)服務(wù)中獲取價(jià)格 當(dāng)斷路器打開時(shí)扁誓,getFallabck()獲取降級(jí)結(jié)果防泵,例如返回緩存價(jià)格 這可以使用Spring的RestTemplate轉(zhuǎn)換為以下代碼:
我們對(duì)上面的例子做一些解釋: 1.該命令封裝產(chǎn)品的id,使用的是UUID蝗敢。 2.Spring的RestTemplate用于進(jìn)行REST調(diào)用捷泞。任何其他選擇都可以。 3.共享Cache實(shí)例寿谴,用于在服務(wù)可用時(shí)緩存產(chǎn)品的價(jià)格锁右。 4.Hystrix命令需要組密鑰,以便在需要時(shí)將它們組合在一起讶泰。 這是Hystrix的另一個(gè)特性咏瑟,超出了本文的范圍。有興趣的讀者可以閱讀Hystrix wiki中的命令組痪署。 5.執(zhí)行對(duì)價(jià)格服務(wù)的調(diào)用.如果調(diào)用失敗码泞,則啟動(dòng)Hystrix斷路器的fall back。 6.如果調(diào)用成功狼犯,則將返回的引用緩存在Cache實(shí)例中的值浦夷。 7.斷路器打開時(shí)調(diào)用getFallback()。 在這種情況下辜王,從緩存中獲取價(jià)格劈狐。 Hystrix wiki具有更高級(jí)的示例,例如 fallback本身就是一個(gè)需要執(zhí)行的命令呐馆。
Spring Cloud和Hystrix集成
雖然上面的代碼有效肥缔,但每次引用時(shí)都需要?jiǎng)?chuàng)建一個(gè)Hystrix命令對(duì)象。 Spring Cloud是一個(gè)構(gòu)建在Spring Boot之上的庫(kù)(它本身構(gòu)建在Spring框架之上)汹来,它提供了與Spring的完美集成续膳。 它允許在處理Hystrix命令對(duì)象的實(shí)例化時(shí),只添加注解在所需的降級(jí)方法上面:
須要在該方法上添加@HystrixCommand](mailto:1.須要在該方法上添加@HystrixCommand)收班。里面的
fallbackMethod``引用了
fallback方法坟岔。當(dāng)然,這將通過(guò)反射來(lái)處理摔桦,并且不是類型安全的 - 畢竟這是一個(gè)字符串社付。Spring Cloud Hystrix允許在方法調(diào)用時(shí)傳遞產(chǎn)品的id參數(shù)承疲。 與上面的簡(jiǎn)單Hystrix命令相比,這允許具有通用服務(wù)對(duì)象鸥咖。 Hystrix命令的創(chuàng)建由Spring Cloud在運(yùn)行時(shí)處理燕鸽。
核心邏輯不會(huì)改變
同樣,緩存處理保持不變啼辣。
fallback方法是一個(gè)普通方法啊研。它將使用與主方法完全相同的參數(shù)值進(jìn)行調(diào)用,因此它必須具有相同的參數(shù)類型(以及相同的順序)鸥拧。 因?yàn)間etQuoteFor()方法接受UUID党远,所以此方法也是如此。
Hystrix富弦,無(wú)論是獨(dú)立的還是由Spring Boot Cloud包裝沟娱,都需要在代碼級(jí)別處理斷路器。 因此舆声,它需要提前計(jì)劃好花沉,并且更改需要部署更新的二進(jìn)制文件。 但是媳握,當(dāng)出現(xiàn)問(wèn)題時(shí)碱屁,可以實(shí)現(xiàn)非常精細(xì)的定制行為。
Istio 和 Hystrix:斷路器之爭(zhēng)
如果事情有可能失敗蛾找,給定時(shí)間娩脾,事情將會(huì)失敗,并且嚴(yán)重依賴網(wǎng)絡(luò)的微服務(wù)需要設(shè)計(jì)為失敗打毛。斷路器模式是處理服務(wù)可用性不足的方法之一:它不是排隊(duì)請(qǐng)求和阻塞調(diào)用者柿赊,而是快速失敗并立即返回。
有兩種方法可以實(shí)現(xiàn)斷路器幻枉,黑盒方式和白盒方式碰声。 Istio作為代理管理工具,采用黑盒方式熬甫。它實(shí)現(xiàn)起來(lái)很簡(jiǎn)單胰挑,它不依賴于底層技術(shù)堆棧,而且它可以事后添加配置信息椿肩。
另一方面瞻颂,Hystrix庫(kù)使用白盒方式。它允許擁有所有不同類型的fallbacks: 單一的默認(rèn)值 緩存 調(diào)用其他服務(wù)
它還提供級(jí)聯(lián)降級(jí)(fallback)郑象。這些附加功能需要付出代價(jià):它需要在仍處于開發(fā)階段時(shí)做出降級(jí)決策贡这。 兩種方法之間的最佳匹配可能取決于不同的場(chǎng)景:在某些情況下,例如引用服務(wù)厂榛,帶有降級(jí)的白盒策略可能更適合盖矫,而對(duì)于其他情況丽惭,快速失敗可能完全可以接受,例如集中式遠(yuǎn)程日志服務(wù)炼彪。 當(dāng)然吐根,你也可以同時(shí)使用它們正歼。
原文:https://www.exoscale.com/syslog/istio-vs-hystrix-circuit-breaker/