Router服務路由, 根據路由規則從多個Invoker當選出1個子集AbstractDirectory是所有目錄服務實現的上層抽象, 它在list羅列出所有invokers后,會在通過Router服務進行路由過濾。
Router接口定義
public interface Router extendsComparable<Router> {
URL getUrl();
<T> List<Invoker<T>> route(List<Invoker<T>>invokers, URL url, Invocation invocation)throws RpcException;
}
ConditionRouter: 條件路由
我們這里簡單分析下代碼實現具體功能參考官方文檔
條件表達式以 => 分割為whenRule和thenRule
ConditionRouter創建,構造器初始
1)從url根據RULE_KEY獲得路由條件路由內容
2)rule.indexOf("=>") 分割路由內容
3)分別調用parseRule(rule) 解析路由為whenRule和thenRules
ConditionRouter履行route方法
1)如果url不滿足when條件即過來條件, 不過濾返回所有invokers
2)遍歷所有invokers判斷是不是滿足then條件, 將滿足條件的加入集合result
3)Result不為空,有滿足條件的invokers返回
4)Result為空, 沒有滿足條件的invokers, 判斷參數FORCE_KEY是不是強迫過來,如果強迫過濾返回空, 不是返回所有即不過濾
ScriptRouter: 腳本路由,
通過url的RULE_KEY參數獲得腳本內容,然后通過java的腳本引擎履行腳本代碼, dubbo的測試用例都是通過javascript作為腳本但是理論上也支持groovy, jruby腳本,大家可以參考下測試用例ScriptRouterTest。
ScriptRouter創建,構造器初始化
1)從url獲得腳本類型javascript, groovy等等
2)從url根據RULE_KEY獲得路由規則內容
3)根據腳本類型獲得java支持的腳本履行引擎
ScriptRouter履行route方法
1)履行引擎創建參數綁定
2)綁定履行的參數
3)履行引擎編譯路由規則得到履行函數CompiledScript
4)CompiledScript.eval(binds) 根據參數履行路由規則
Dubbo提供了ConditionRouterFactory, ScriptRouterFactory來創建對應的路由,路由的規則從url的RULE_KEY參數來獲得,路由規則可以通過監控中心或治理中心寫入注冊中心
RegistryFactory registryFactory =ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry =registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181");
registry.register(URL.valueOf("condition://0.0.0.0/com.foo.BarService?category=routers&dynamic=false&rule="+ URL.encode("http://10.20.160.198/wiki/display/dubbo/host = 10.20.153.10=> host = 10.20.153.11") + "));
Dubbo也支持通過FileRouterFactory從文件讀取路由規則,將讀取的規則設置到url的RULE_KEY參數上, 文件的后綴代表了路由的類型,選擇具體的路由工廠 ConditionRouterFactory,ScriptRouterFactory來創建路由規則