16. Dubbo原理解析-集群&容错之router路由服务

Router服务路由, 根据路由规则从多个Invoker中选出一个子集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来创建路由规则

代码交流 2021