1. 問題
如何設(shè)計dubbo的集群,如何配置和設(shè)計dubbo負(fù)載均衡策略,如何路由服務(wù)?針對這些問題,我們來理解dubbo的幾個類:AbstractClusterInvoker,Directory,LoadBalance,Router這幾個類之間的關(guān)系。
2. 描述
2.1 AbstractClusterInvoker的invoke流程
AbstractClusterInvoker作為一個Invoker,它是dubbo的核心概念,在dubbo的開發(fā)文檔中有如下解釋:它代表一個可執(zhí)行體,可向它發(fā)起invoke調(diào)用,它有可能是一個本地的實現(xiàn),也可能是一個遠(yuǎn)程的實現(xiàn),也可能一個集群實現(xiàn)。而這里就是一種集群實現(xiàn)。其核心過程也是invoke調(diào)用的過程。下圖就是調(diào)用的序列圖:
這張序列圖主要描述了集群Invoker和Directory、Router、LoadBalance之間的交互。最后的Invoker表示抽象集群Invoker的各種具體類。
這里我們主要思考:這個流程中Directory主要解決了什么問題?Rounter又解決了什么的問題?使用EntensionLoader加載具體LoadBalance又什么樣的好處?
2.2 Directory的類體系結(jié)構(gòu)
RegisterDirectory實現(xiàn)了doList,主要通過invocation對象中獲取methodName和argument,并組成key,從localMethodInvokeMap中獲取invokes。這里對key做了四種場景考慮:
1. 存在參數(shù)時
2. 根據(jù)方法名
3.根據(jù)匹配符Any(*)
4. 獲取localMethodInvokeMap第一個key對應(yīng)的invokers列表
但是RegisterDirectory還可以做很多其他事情,同時這里要考慮localMethodInvokeMap是什么時候出初始化的,通過什么內(nèi)容來初始化。
這里主要說明在createRegistry的過程中,會調(diào)用RegistryDirectory的notify和subscribe的方法,而notify和subscribe主要實現(xiàn)了什么,我們繼續(xù)分析其里面的源代碼。
notify首先更加protocol和category來劃分invokeUrls、routerUrls和configuratorUrls。然后,根據(jù)各個urls來初始化RegistryDirectory中成員變量configurators、routers。配置overrideDirectoryUrl,最后根據(jù)invokerUrls來refreshInvoker。
接下去我們需要考慮如何通過url生成configurators、routers和invokers;