微服務熔斷隔離機制及注意事項


(用友雲平臺-基礎平臺服務[gPaaS])技術架構師

導讀:本文重點分析微服務化過程中熔斷機制及應用注意事項,包括微服務調用與“雪崩效應”及解決方案、熔斷機制及考慮因素、隔離機制及實現方式考量等內容。

隨著企業微服務化戰略的實施,業務功能細分,越來越多的服務從原有的單體應用中分解成一系列獨立開發、部署、運維的微小服務,服務之間則依賴於各種RPC框架互相通信。縱然,微服務化有著很多優勢,但與之伴隨而來的是各種複雜性,對開發人員來說,除了業務領域本身外,還需要考慮由於服務拆分之後諸如分佈式事務、服務部署及運維、rpc調用等系列問題,本文將重點分析微服務化過程中熔斷機制及應用注意事項。

微服務調用與“雪崩效應”:

微服務化之後服務之間調用關係複雜,調用層級深,服務之間依靠rpc框架進行通信,如下圖1,實線是同步rpc調用,虛


微服務熔斷隔離機制及注意事項


圖1 服務調用關係

線則是異步rpc調用,整個調用鏈路從webapi開始到dinnerservice結束,紅色節點則表示該服務不可用或高延遲,異步調用msgservice異常對鏈路返回結果並無影響,而同步調用(memberservice服務)的性能對鏈路則有很大影響,其會造成鏈路上planeservice、orderservice及webapi服務堵住,堵著的請求會耗費線程及io資源,隨著此類請求越來越多,特別是在流量高峰時,如果不能及時解決memberservice的問題,最終將把整條鏈路堵死,造成webapi不能對外提供服務,提供崩潰,這就是所謂的雪崩效應。

雪崩效應解決方案:

針對雪崩效應的情況,通常我們可以有如下幾中方案來解決。

一、同步調用異步化方案。如圖所示,異步調用對於調用方來說,不會造成堵塞,從而將調用方保護起來。因此,可從業務層面設計入手,將不需要及時返回結果的業務調用設計成異步來調用。典型場景,註冊驗證碼發送,消息通知等。

二、限流方案。通過限制入口流量,將併發限制在一定範圍內,能在一定程度上避免雪崩效應,如果不可用服務是部分不可用或超時時。

以上方案都不能徹底解決問題癥結,那真正比較可行的則是第三種,應用熔斷隔離機制的方案。熔斷,就像電路短路,當電壓過高,負載加重時,保險絲就會自動斷開,避免事故發生。在微服務中,當鏈路上某個服務不可用或延遲嚴重,達到熔斷器設定指標閾值時,則觸發熔斷機制,對於後續請求直接返回默認結果或拋出異常,避免整個鏈路因為部分服務不可用而雪崩。隔離則是服務調用方將耗時的方法或rpc調用與業務代碼隔離開來,避免耗時方法或rpc調用造成服務堵塞。

熔斷機制及考慮因素:

熔斷機制具體實現體現為一個熔斷器,如何實現熔斷器,主要考慮以下幾個方面。

第一,熔斷請求判斷算法即熔斷在什麼條件處於開啟狀態,什麼條件處於關閉或半關閉狀態。使用滑動時間窗口來記錄每個時間片內相關熔斷計數指標及熔斷器狀態,這個時間片段稱作為一個bucket,默認維護10個bucket,每1秒一個bucket,隨著時間的滾動,最早的bucket拋棄,創建新的bucket到滑動窗口右邊。每個blucket記錄請求總數、成功數、超時數、拒絕數及熔斷器狀態,默認錯誤超過50%且10秒內超過20個請求進行中斷攔截。


微服務熔斷隔離機制及注意事項


圖2 滑動窗口

第二、熔斷恢復。默認情況下,熔斷器處於閉合狀態,當熔斷指標達到閾值時,熔斷器狀態變為打開狀態,此時,所有請求直接返回或拋出異常。過了一段時間後,後端異常服務經過開發運維人員及時解決了問題,熔斷器如何知曉呢?如果沒有一定的熔斷恢復機制,那一旦熔斷器打開,就不能再閉合上,顯然不合情理。因此,熔斷器需要有放行規則,對於熔斷器開啟狀態超5s以內的請求,直接熔斷,如果熔斷器開啟超過5s,則進入半開啟狀態,可以按一定規則,允許部分請求通過,試探性的調用被隔離的服務,若請求如是健康狀態,則恢復關閉熔斷器,如下圖3是熔斷器狀態轉換關係。


微服務熔斷隔離機制及注意事項


圖3熔斷器狀態轉換

第三、熔斷後如何處理請求。當熔斷器處於打開狀態時,請求直接返回,業務如何知道當前發生了狀況?可向業務層拋出特定異常,用於標識當前熔斷器打開,但熔斷器通常通過降級措施來處理,提供提供降級接口或實現,由熔斷器自行處理降級措施,開發人員只需要實現降級邏輯即可,其它事情就交給熔斷器來處理。

隔離機制及實現方式考量:

隔離機制也是為了保護微服務鏈路調用中避免雪崩效應的一種策略,與熔斷配合使用,隔離機制可以有兩種實現。

一、線程池隔離模式:使用一個線程池來存儲當前的請求,線程池對請求作處理,設置任務返回處理超時時間,堆積的請求堆積入線程池隊列。這種方式需要為每個依賴的服務申請線程池,有一定的資源消耗,好處是可以應對突發流量(流量洪峰來臨時,處理不完可將數據存儲到線程池隊裡慢慢處理)。

二、信號量隔離模式:使用一個原子計數器(或信號量)來記錄當前有多少個線程在運行,請求來先判斷計數器的數值,若超過設置的最大線程個數則丟棄改類型的新請求,若不超過則執行計數操作請求來計數器+1,請求返回計數器-1.這種方式是嚴格的控制線程且立即返回模式,無法應對突發流量(流量洪峰來臨時,處理的線程超過數量,其他的請求會直接返回,不繼續去請求依賴的服務)。

線程池隔和限號量隔離機制各有利弊,在使用信號量隔離時,最大的弊端是不能實現超時返回,這有時對業務是致命的,一旦後端服務超時時間過長,已經發起的調用無法及時返回,導致資源堵塞,調用方長時間等待。而線程池隔離機制可以解決超時返回的問題,線程池隔離機制問題在於在微服務之間通過rpc調用,無論是我們自研的rpc框架,還是開源的rpc框架如dububo等,都可能會使用Threadlocal來緩存本地線程變量來傳遞上下文信息,服務端接收到調用的傳過來請求時,需要將請求中附帶的上下文信息保存到當前線程的Threadlocal變量中,當服務端調用其它其它服務時,需要將上下文信息從Threadlocal取出來再傳遞給下游服務,在tomcat線程模型下工作正常,但此時如果將對rpc的調用進行線程隔離後,由於線程複用問題,導致在隔離線程中執行rpc調用時服務獲取不到調用線程中的Threadlocal變量,這會導致鏈路跟蹤信息無法傳遞等問題,在實踐中需要引起特別注意,此問題關鍵是要解決跨線程間Threadlocal變量傳遞,至於如何傳遞,可以參考jdk的InheritableThreadlocal機制,他解決了父子進程間Threadlocal變量繼承問題,提供了一種解決此問題的思路,但線程隔離機制,比如Hystrix通常都是通過線程池來實現,避免反覆創建銷燬線程帶來的性能損耗,但隔離線程與調用線程沒有父子關係,因此需要自行解決Threadlocal變量跨線程的問題。

微服務治理平臺是iuap基礎平臺服務(gPaaS)的一個核心能力。企業在向“互聯化”方向轉型的過程中,軟件產品的開發需求變更越來越頻繁,對技術中臺要求越來越強烈,統一的gPaaS基礎能力逐漸被認可,越來越多的企業期望有一個基礎平臺去支撐企業快速增長的業務。gPaaS基礎平臺是iuap產品家族的一部分,提供了DevOps能力、容器雲能力、服務治理能力、微服務編排能力。gPaaS基礎平臺簡化了多種基礎設施帶來的複雜性,打通了開發運維一體化流程,提供傳統服務架構向微服務架構轉變及服務治理的最佳方法論和工具集,支持微服務可視化編排。


分享到:


相關文章: