Dubbo源码分析(九)-----Router的路由的过滤器链分析

971 阅读4分钟

Dubbo版本2.7.3.Release. 上一篇中分了Directory中经过RouteChain转化成Invoker,本篇文章介绍调用的第二步,Router 的实现。首先看下RouteFactory的扩展点,默认是没有,通过URL中protoco中的值选择使用对应的扩展点, Router 负责从多个 Invoker 中按路由规则选出子集,比如灰度、路由等 也就是说,第一步通过 Directory 选出当前可用的服务提供者,然后再通过 Router 按规则过滤出服务提供者的子集。

从这里可以看出有这七种扩展点,都是实现RouteFactory的, 里面实现的也比较简单,直接new 一个对应的Ruuter并返回 例如ScriptRouterFactory直接new一个ScriptRouter,但是 FileRouterFactory则是在工厂里面实现了所有的逻辑
其中条件路由参数规则: 条件路由使用的是conditon://协议,URL形式是"conditon://0.0.0.0//com.foo.DemoService?catatory-router&dynamic=false&rule="+URL.encode("host=10.20.154.10 => host=10.20.153.11"),最后路由参数会以URL.encode进行编码,下面看下官方文档中对每一个 参数含义说明:

参数名称 含义
condition:// 表示路由规则类型,支持条件路由和脚本路由
0.0.0.0 表示对所有IP地址生效,如果只想对某个IP生效,则填入具体IP
com.foo.DemoService 表示指定服务生效
category=routers 表示只对指定服务生效,必填
dynamic=false 表示该数据为持久化存储,当注册方退出时,数据依然保存在数据中心
enable=true 覆盖规则是否生效,可不填,默认生效
force=false 当路由结果为空时,是否强制执行,如果不强制执行,则路由结果为空的路由规则将自动失效
runtime=false 是否在每次调用时执行路由规则,否则只在提供者列表变更时预先执行并缓存结果,调用时直接从缓存中获取路由结果,如果使用参数路由,必须设置为true,注意设置会影响性能,默认是false
priority=1 路由规则的优先级,用于排序,优先级越大越靠钱执行,可不填,默认为0
rule=URL.encode("host=10.20.153.10 => host = 10.20.153.11") 表示路由规则的内容,必填

路由规则配置:

method = find* => host=192.168.3.201
  • 这条配置说明调用所有find开头的方法都会被路由到IP为192.168.3.201的服务节点,
  • => 之前的部分消费者匹配条件,将所有的参数和消费者的URL进行对比, 当消费者满足匹配 条件时,对该消费者执行后面的过滤规则.
  • => 之后部分为提供者地址列表的过滤条件,将所有的参数和提供者的URL进行对比,消费者最终只获取过滤后的地址列表
  • 如果匹配条件给空, 则表示用于所有的消费方, 如: => host != =192.168.3.201.
  • 如果过滤条件为空,则表示禁止访问,如 host = =192.168.3.201=>. 整个规则的表达式的支持protocol,usernmae,password,host,port,path等占位方式,也支持=、!=等条件,值可以是多个,用逗号分隔,如host=192.168.3.201,192.168.3.202,如果是以*号结尾, 则表示通配符,如host=192.168.3.* 表示匹配192.168.3.网段下所有的IP.

下面是ConditionRouter的实现,初始化rule时,会解析路由规则,通过分隔符“=>”, 前面是消 费着的过滤条件,后面是提供者过滤条件.

从解析规则来看,初始化时调用parseRule,通过正则表达式不循环匹配whenRule和thenRule字段串, 解析会根据分隔符分类(如果A=B,则=是分隔符),支持分隔符形式:A=B,A&B,A1=B,A,B这四种形式,最终会封装一个MathcherPair对象,以上面的路由配置为例,whenMap对象,key是参数method的值,value则是封装了的find*的MartchPair对象.thenMap对象则是保存key是host的值,value是192.168.3.201的MatherPair
接下来就是调用route进行路的具体逻辑, 1,检验, 如果没有启动,则直接返回,如果没有匹配 任何的whenRule匹配,则直接返回传入的invoker列表, 如果有匹配上whenRule,但是thenRule 为空,即没有匹配上规则的invoker,则返回空,2,如果匹配上whenRule,则遍历thenRule找出所有符合规则的invoker加入集合, 3,返回结果,如果结果鸡为空,如果规则配置了force=true, 表示强制过滤,则返回空,否则会返回所有的invoker列表

总结
今天就Dubbo的Route的路由配置和源码解析和执行的过程分析,下一篇会着重分析Invoker抽象的调用逻辑