1. 程式人生 > >原始碼分析Dubbo Invoker概述----服務發現、叢集、負載均衡、路由體系

原始碼分析Dubbo Invoker概述----服務發現、叢集、負載均衡、路由體系

Invoker,負載網路呼叫元件,底層依懶與網路通訊,Invoker主要負責服務呼叫,自然與路由(比如叢集)等功能息息相關,本節先從整體上把控一下Dubbo服務呼叫體系,服務發現、叢集、負載均衡、路由機制等整個知識體系,梳理整理Dubbo Invoker整個類圖如下:
這裡寫圖片描述
主要有如下介面群
1、Invocation(呼叫上下文環境)
1.1 Invocation:
1)String getMethodName() 獲取呼叫方法名。
2)Class< ? >[] getParameterTypes() 獲取被呼叫方法的引數列表(引數型別)
3)Object[] getArguments() 獲取被呼叫方法的引數值陣列。
4)Map< String, String> getAttachments() 獲取附加屬性。
5)String getAttachment(String key) 根據key獲取附加屬性值。
6)String getAttachment(String key, String defaultValue) 根據key獲取附加屬性,如果不存在,取預設值。
7)Invoker< ?> getInvoker() 獲取當前的invoker。
1.2 RpcInvocation rpc服務呼叫實現類
Invocation執行呼叫上下文環境,就是用一個Bean儲存當前呼叫方法的引數,其本質就是一個普通的Bean而已。
1.3 MockInvocation
用於mock單元測試用。
1.4 DecodeableRpcInvocation 帶解碼功能的rpc呼叫上下文
該實現主要能從RPC服務呼叫請求中解析二進位制流(二進位制包)得到RPC服務呼叫上下文(方法呼叫元資料)。

2、Invoker 服務呼叫器,Dubbo中呼叫服務的抽象。
Invoer的抽象介面,繼承自com.alibaba.dubbo.common.Node介面
Node:
URL getUrl(); 獲取URL,在dubbo中,註冊中心、服務提供者、服務消費者、監控中心等都使用URL描述。
boolean isAvailable() :判斷是否可用。
void destroy() :資源銷燬。
Invoker:
Class getInterface() :獲取服務提供者的介面。
Result invoke(Invocation invocation) throws RpcException :呼叫服務,返回呼叫結果。
2.1 AbstractInvoker Invoker預設實現(模板類)
該方法主要實現public Result invoke(Invocation inv) throws RpcException,定義執行invoker的基礎流程(模板),然後根據不同的實現子類(不同的協議)執行各自個性化的執行任務。其抽象方法:protected abstract Result doInvoke(Invocation invocation) throws Throwable,具體實現將在後文中分析。
2.1.1 DubboInvoker dubbo協議呼叫器具體實現。
2.1.2 InjvmInvoker injvm協議呼叫其具體實現(本地協議)
2.2 AbstractClusterInvoker 叢集模式呼叫模板類
該類為Dubbo叢集模式的呼叫模板類,主題解決一個服務服務有多個服務提供者,此時訊息消費端在呼叫服務時如何選擇具體的服務提供者。該類需要組織多個服務提供者,並按照指定演算法選擇一服務提供者進行呼叫。
2.2.1 AvailableClusterInvoker
通過< dubbo:service cluster = “available” …/> 或 < dubbo:reference cluster=”available” …/>
叢集策略:總是選擇第一個可用的服務提供者。
2.2.2 BroadcastClusterInvoker
通過< dubbo:service cluster = “broadcast” …/> 或 < dubbo:reference cluster=”broadcast” …/>
叢集策略:廣播模式,向所有服務提供者都發送請求,任何一個呼叫失敗,則認為失敗。
2.2.3 FailbackClusterInvoker
通過< dubbo:service cluster = “failback” …/> 或 < dubbo:reference cluster=”failback” …/>
叢集策略:服務呼叫失敗後,定時重試,重試次數無線次,重試頻率:5s。並不會切換服務提供者。
2.2.4 FailfastClusterInvoker
通過< dubbo:service cluster = “failfast” …/> 或 < dubbo:reference cluster=”failfast” …/>
叢集策略:服務呼叫後,快速失敗,直接丟擲異常,並不重試,也不受retries引數的制約,適合新增、修改類操作。
2.2.5 FailoverClusterInvoker
通過< dubbo:service cluster = “failover” …/> 或 < dubbo:reference cluster=”failover” …/>
叢集策略:服務呼叫後,如果出現失敗,則重試其他服務提供者,預設重試2次,總共執行3次,重試次數由retries配置,dubbo叢集預設方式。
2.2.6 FailsafeClusterInvoker
通過< dubbo:service cluster = “failsafe” …/> 或 < dubbo:reference cluster=”failsafe” …/>
叢集策略:服務呼叫後,只打印錯誤日誌,然後直接返回。
2.2.7 ForkingClusterInvoker
通過< dubbo:service cluster = “forking” …/> 或 < dubbo:reference cluster=”forking” …/>
叢集策略:併發呼叫多個服務提供者,取第一個返回的結果。可以通過forks設定併發呼叫的服務檯提供者個數。
更多的叢集策略,可以參考/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.cluster.Cluster檔案:
這裡寫圖片描述


3、LoadBalance 叢集負載演算法
當一個服務有多個服務提供者時,消費端在進行服務呼叫時選擇服務服務提供者的負載均衡演算法。
LoadBalance定義的介面為:
< T> Invoker select(List< Invoker> invokers, URL url, Invocation invocation) throws RpcException;
3.1 ConsistentHashLoadBalance
可以通過< dubbo:service loadbalance=”consistenthash” …/>或< dubbo:service loadbalance = “consistenthash” …/>
負載均衡演算法:一致性Hash演算法,在AbstractClusterInvoker中從多個服務提供者中選擇一個服務提供者時被呼叫。
3.2 LeastActiveLoadBalance
可以通過< dubbo:service loadbalance=”leastactive” …/>或< dubbo:service loadbalance = “leastactive” …/>
負載均衡演算法:最小活躍呼叫。
可以通過< dubbo:service loadbalance=”random” …/>或< dubbo:service loadbalance = “random” …/>
負載均衡演算法:隨機,如果weight(權重越大,機會越高)
3.4 RandomLoadBalance
可以通過< dubbo:service loadbalance=”roundrobin” …/>或< dubbo:service loadbalance = “roundrobin” …/>
負載均衡演算法:加權輪詢演算法。
4、Directory(目錄服務,Invoker的目錄服務)
該介面主要的作用是服務提供者的目錄服務,管理多個服務提供者。
4.1 Directory
1)Class< T> getInterface() 獲取該服務介面類別。
2)List< Invoker< T>> list(Invocation invocation) throws RpcException 根據呼叫上下文獲取當前所有該服務的服務提供者。
4.2 AbstractDirectory 目錄服務實現的抽象列(模板類)
4.3 StaticDirectory 靜態目錄服務
所謂靜態目錄服務就是在建立StaticDirectory時指定一個服務提供者集合,則該目錄服務例項在其生命週期中,只會返回這些服務提供者。
4.4 RegistryDirectory 動態目錄服務(基於註冊中心)、
從註冊中心動態獲取發現服務提供,預設訊息消費者並不會指定特定的服務提供者URL,所以會向註冊中心訂閱服務的服務提供者(監聽註冊中心providers目錄),利用RegistryDirectory自動獲取註冊中心伺服器列表。
5、Router 路由功能
根據訊息消費者URL,結合路由表示式或JS引擎,從Directory中選擇符合路由規則的Invoker,再執行負載均衡演算法。
5.1 Router
1)URL getUrl(); 獲取訊息消費者URL。
2)< T> List< Invoker< T>> route(List< Invoker< T>> invokers, URL url, Invocation invocation) throws RpcException 根據訊息消費者URL,從invokers中篩選合適的Invokers。
5.2 ConditionRouter 基於條件表示式的路由實現。
5.3 ScriptRouter 基於JS引擎的路由實現。

單個Invoker的實現,例如DubboInvoker、InJVMInvoker底層呼叫網路通道傳送請求命令(oneway、同步、非同步呼叫方式),其網路底層細節將在後續專門講解網路實現篇章重點分析,接下來的篇章,主要從原始碼的角度剖析叢集、負載均衡、動態路由目錄服務(RegistryDirectory )的實現細節。