Dubbo調優 -- 限流策略

一:前情導讀

高併發環境下若生產者不能及時處理請求造成大量請求線程積壓,最終會演變爲大面積服務崩潰現象產生。根據服務特點設定合理的請求拒絕策略,保證服務正常運行是本文重點。當然必須區別於負載均衡只能分配流量而不能限制流量
在這裏插入圖片描述

二:消費端actives

僅針對消費者端生效,只能在<dubbo:reference>亦或是其子標籤<dubbo:method>或者是<dubbo:consumer>中配置。優先級策略與文章Dubbo調優 – 超時TimeOut描述一致

2.1 配置示例
2.2 參數詳解
描述 備註
作用 消費者最大併發數量限制,超過限制將會拋出異常
實現 過濾器Filter,具體實現子類爲ActiveLimitFilter
默認值 0表示沒有限制
配置地點 <dubbo:consumer>、<dubbo:reference> 、<dubbo:method>
2.3 源碼導讀

在這裏插入圖片描述

  1. 處理請求參數:URL爲Dubbo封裝的一個請求對象類,包含Map<String, String>類型屬性numbers,該屬性中含有actives配置
  2. 請求過濾判斷:RpcStatus類封裝生產者調用狀態,AtomicInteger原子類型active屬性存儲當前調用數量。通過其與URL中獲取到的對應參數屬性值比較判斷
  3. 請求返回結果:如果允許則進行下一步RPC調用,不允許則會暫停等待線程timeout參數時長,若喚醒還未有空餘線程則拋出異常

三:消費端connections

大家熟悉的HTTP協議就屬於短連接,每次請求的時候都會多次驗證握手建立連接。默認的Dubbo協議屬於長連接,採用NIO異步傳輸,每消費者與生產者之間默認採用單一長連接方式通信。換個簡單說法就是每個消費者與生產者之間長連接默認就創建一個,所有請求共用

connections參數針對上述長連接與短連接具備不同作用效果:

  • 短連接因爲是多連接所以限制其個數
  • 長連接因爲是單一連接所以是指定其創建數量
3.1 配置示例

connections參數生效的位置在消費端,圖一表示消費端的配置,圖二表示在生產者的配置。根據自身測試以及github驗證,生產端的配置確實會通過註冊中心傳遞給消費端生效
在這裏插入圖片描述
在這裏插入圖片描述

3.2 參數詳解
描述 備註
作用 限制消費者短連接數量,長連接創建數量
實現 初始化連接時根據參數控制
默認值 長連接默認表示使用JVM共享長連接,線上一般都是多生產多消費,這個參數不建議更改
配置地點 <dubbo:consumer>、<dubbo:reference> 、<dubbo:provider>、<dubbo:service>
3.3 源碼導讀

首先項目初始化的時候會根據connections參數初始化連接,過程在DubboProtocol類的getClients()方法中,下圖是debug跟進的初始化結果。可以看到用於儲存連接的數組最後返回的是兩個連接實例
在這裏插入圖片描述
連接使用發生在類DubboInvoker中,該類的方法doInvoke()用於執行調用邏輯。使用的連接就是在DubboProtocol類中getClients()初始化出來並在方法refer()中放入DubboInvoker對象的連接。如下圖所示是DubboInvoker中doIncoke()使用連接的關鍵代碼
在這裏插入圖片描述

四:生產端accepts

消費者可以通過connections參數設置連接的數量,但是如果生產者不進行自我保護,採用默認的無限制連接策略。高併發情況下生產者可能就會因爲連接數量巨大崩潰,這時可以通過參數accepts限制生產者可接受最大連接數量

4.1 配置示例

accepts用於生產者限制最大連接數量保護自身服務可用性,可以在標籤<dubbo:protocol>中進行配置。這時候在<dubbo:reference>中設置connections超過accepts值,用於方便後續的源碼跟進
在這裏插入圖片描述
在這裏插入圖片描述

4.2 參數詳解
描述 備註
作用 限制生產者最大可接受連接數量,用於保護生產者自身
實現 消費者初始化創建連接時會打開創建鏈接,這時候就會根據限制參數判斷
默認值 0表示沒有限制,比較危險的配置
配置地點 <dubbo:protocol>
4.3 源碼導讀

生產者啓動初始化過程中可以看到開啓連接的時候獲取了參數accepts的設置,過程在AbstractServer類構造函數中可以看到
在這裏插入圖片描述
消費端初始化的時候當超過生產者限制連接數量後,在AbstractClient類中可以看到,構造函數中調用方法connect()創建連接。這時候會拋出異常,因爲異常原因是等待創建連接超時3000ms。驗證參數accepts效果
在這裏插入圖片描述

五:生產端線程池

多線程併發操作一定離不開線程池,Dubbo自身提供了支持了四種線程池類型支持。生產者<dubbo:protocol>標籤中可配置線程池關鍵參數,線程池類型、阻塞隊列大小、核心線程數量等

5.1 iothreads、threads
  • iothreads:限制的是io線程池大小,該線程池線程用於處理Dubbo框架自身業務邏輯。默認值爲CPU+1,不建議更改設置
  • threads:用於指定下面講到的業務線程池線程數量,這個纔是業務需要關心的線程數量。默認大小200
5.2 threadpool

參數threadpool指定使用線程池類型,Dubbo中自身實現提供瞭如下表所示四種線程池。默認使用固定大小線程池FixedThreadPool

類型名稱 隊列類型 特性備註
FixedThreadPool queues屬性爲0創建無容量阻塞隊列SynchronousQueue,若 queues小於0則創建Integer.MAX_VALUE容量LinkedBlockingQueue阻塞隊列,大於0則創建 queues參數限定容量LinkedBlockingQueue阻塞隊列 核心線程數量與最大線程數量一致採用參數threads值、線程空閒存活時間0
CachedThreadPool 隊列創建類型規則與FixedThreadPool一致 相對於固定容量大小FixedThreadPool線程池多了參數corethreads設置核心線程數量支持默認0,線程空閒存活時間暫時未提供參數設置,默認1分鐘
LimitedThreadPool 隊列創建類型規則與FixedThreadPool一致 相對於CachedThradPool而言最大的變化在於線程存活時間修改爲Long.MAX_VALUE
EagerThreadPool 隊列爲Dubbo設計實現的TaskQueue隊列,該隊列繼承自LinkedBlockingQueue。當queues參數小於等於0則其容量爲1,若大於0則容量爲queues參數值 後面會有專門文章研究這個線程池實現
5.3 注意

Dubbo官網文檔只描述了fixed/cached,四種線程池默認支持的是fixed

六:生產端executes

一個只能在生產者即dubbo:service亦或是其子標籤dubbo:method中配置的屬性,消費者中配置不會生效。這個參數主要目的是在生產者端限制應用線程使用數量

6.1 配置示例

限制該服務每個方法併發不超過10,其中dubboProtocolGetMethod方法併發不超過2。方法級別的配置優先級高於服務配置
在這裏插入圖片描述

6.2 參數詳解
配置地點 生產者dubbo:service標籤或其子標籤dubbo:method
默認值 0表示沒有限制
作用 服務提供者每個方法只能佔用線程池中配置數量線程,超出則拋出異常
實現 過濾器Filter
6.3 源碼導讀
  • 主要涉及類:ExecuteLimitFilter,關注相關類RpcStatus、URL
  • 主要方法:getMethodParameter()、beginCount()、getStatus()
    在這裏插入圖片描述
  1. 處理請求參數,URL爲Dubbo封裝的一個請求對象類,包含Map<String, String>類型屬性numbers,該屬性中含有executes配置
  2. 提取executes參數值,numbers – paramters – 默認值順序返回
  3. 比較executes值數量,RpcStatus類封裝生產者調用狀態,AtomicInteger原子類型active屬性存儲當前調用數量
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章