Dubbo 的流量防衛兵|Sentinel如何通過限流實現服務的高可用性

在複雜的生產環境下可能部署著成千上萬的服務實例,當流量持續不斷地湧入,服務之間相互調用頻率陡增時,會產生系統負載過高、網絡延遲等一系列問題,從而導致某些服務不可用。如果不進行相應的流量控制,可能會導致級聯故障,並影響到服務的可用性,因此如何對高流量進行合理控制,成為保障服務穩定性的關鍵。

Dubbo 的流量防衛兵|Sentinel如何通過限流實現服務的高可用性

阿里巴巴中間件團隊在上週的Aliware Open Source 深圳站的活動上,宣佈對Sentinel開源,並在社區發佈了首個開源版本v0.1.0。Sentinel是面向分佈式服務架構的輕量級限流降級框架,以流量為切入點,從流量控制、熔斷降級和系統負載保護等多個維度來幫助用戶保障服務的穩定性。從本期開始,我們將圍繞Sentinel的使用場景、技術對比和實現、開發者實踐等維度推出系列文章。本文將基於Dubbo的服務框架,看看Sentinel 是如何對高流量進行限流的。

一、Dubbo 一鍵接入 Sentinel

Sentinel 意為哨兵,這個命名形象的詮釋了Sentinel在分佈式系統中的工作角色和重要性。 以 Sentinel 在Dubbo 生態系統中的作用為例,Dubbo服務框架的核心模塊包括註冊中心、服務提供方、服務消費方(服務調用方)和監控4個模塊。Sentinel通過對服務提供方和服務消費方的限流來進一步提升服務的可用性。接下來我們看看Sentinel對服務提供方和服務消費方限流的技術實現方式。

Dubbo 的流量防衛兵|Sentinel如何通過限流實現服務的高可用性

Sentinel 提供了與 Dubbo 適配的模塊 – Sentinel Dubbo Adapter,包括針對服務提供方的過濾器和服務消費方的過濾器。使用時用戶只需引入相關模塊,Dubbo的服務接口和方法(包括調用端和服務端)就會成為 Sentinel 中的資源,在配置了規則後就可以自動享受到 Sentinel 的防護能力。同時提供了靈活的配置選項,例如若不希望開啟Sentinel Dubbo Adapter中的某個Filter,可以手動關閉對應的Filter。

二、限流必備 - 監控管理

流量具有很強的實時性,之所以需要限流,是因為我們無法對流量的到來作出精確的預判,不然的話我們完全可以通過彈性的計算資源來處理,所以這時候為了保證限流的準確性,限流框架的監控功能就非常重要了。

Sentinel的控制檯(Dashboard)是流量控制、熔斷降級規則統一配置和管理的入口,同時它為用戶提供了多個維度的監控功能。在Sentinel控制檯上,我們可以配置規則並實時查看流量控制效果。

» 單臺設備監控

當在機器列表中看到您的機器,就代表著已經成功接入控制檯,可以查看單臺設備的設備名稱、IP地址、端口號、健康狀態和心跳時間等信息。

Dubbo 的流量防衛兵|Sentinel如何通過限流實現服務的高可用性

» 鏈路監控

簇點鏈路實時的去拉取指定客戶端資源的運行情況,它提供了兩種展示模式,一種用書狀結構展示資源的調用鏈路;另外一種則不區分調用鏈路展示資源的運行情況。通過鏈路監控,可以查看到每個資源的流控和降級的歷史狀態。

Dubbo 的流量防衛兵|Sentinel如何通過限流實現服務的高可用性

» 聚合監控同一個服務下的所有機器的簇點信息會被彙總,實現實時監控,精確度達秒級。

Dubbo 的流量防衛兵|Sentinel如何通過限流實現服務的高可用性

三、Sentinel 基於 Dubbo的最佳實踐

Dubbo 接入 Sentinel後,可通過對Dubbo核心模塊中的服務提供方和服務消費方的限流來進一步提升服務的可用性。

1、對服務提供方的限流

對服務提供方的限流可分為服務提供方的自我保護能力和服務提供方對服務消費方的請求分配能力這兩個維度。

服務提供方用於向外界提供服務,處理各個消費方的調用請求。為了保護提供方不被激增的流量拖垮影響穩定性,可以給提供方配置QPS模式的限流,這樣當每秒的請求量超過設定的閾值時會自動拒絕閾值外的請求。若希望整個服務接口的QPS不超過一定數值,則可以為對應服務接口資源(resourceName為接口全限定名)配置QPS閾值;若希望對某個服務函數的QPS不超過一定數值,則可以為對這個服務函數資源(resourceName為接口全限定名:方法簽名)配置QPS閾值。

根據調用方的需求來分配服務提供方的處理能力也是常見的限流方式。比如有兩個服務 A 和 B 都向 Service Provider 發起調用請求,我們希望只對來自服務 B 的請求進行限流,則可以設置限流規則的 limitApp 為服務 B 的名稱。Sentinel Dubbo Adapter 會自動解析 Dubbo 消費方(調用方)的 application name 作為調用方名稱(origin),在進行資源保護的時候都會帶上調用方名稱。若限流規則未配置調用方(default),則該限流規則對所有調用方生效。若限流規則配置了調用方則限流規則將僅對指定調用方生效。

2、對服務消費方的限流

對服務提供方的限流可分為對控制併發線程數,和服務降級兩個維度。

服務消費方作為客戶端去調用遠程服務。每一個服務都可能會依賴幾個下游服務,若某個服務A依賴的下游服務B出現了不穩定的情況,服務A請求服務B的響應時間變長,從而服務A調服務B的線程就會產生堆積,最終可能耗盡服務A的線程數。我們通過用併發線程數來控制對下游服務B的訪問,來保證下游服務不可靠的時候,不會拖垮服務自身。採用基於線程數的限制模式後,我們不需要再去對線程池進行隔離,Sentinel 會控制資源的線程數,超出的請求直接拒絕,直到堆積的線程處理完成。限流粒度同樣可以是服務接口和服務方法兩種粒度。

我們看一下這種模式的效果。假設當前服務A依賴兩個遠程服務方法 sayHello(java.lang.String) 和 doAnother()。前者遠程調用的響應時間為1s-1.5s之間,後者RT非常小(30 ms左右)。服務A端設兩個遠程方法線程數為5,然後每隔50 ms左右向線程池投入兩個任務,作為調用者分別遠程調用對應方法,持續10次。可以看到 sayHello 方法被限流5次,因為後面調用的時候前面的遠程調用還未返回(RT高);而 doAnother() 調用則不受影響。線程數目超出時快速失敗能夠有效地防止自己被調用所影響。

此外,當調用鏈路中某個資源出現不穩定的情況,如平均 RT 增高、異常比例升高的時候,Sentinel 會使對此調用資源進行降級操作。

以上介紹的只是Sentinel的一個最簡單的場景 – 限流,Sentinel還可以處理更復雜的場景,例如 請求勻速、超時熔斷、冷啟動 等,下一期我們將分享如何藉助Sentinel實現消息流轉場景下的請求勻速功能。


分享到:


相關文章: