摘要
Router 的主要功能就是根据用户配置的路由规则以及请求携带的信息,过滤出符合条件的 Invoker 集合,供后续负载均衡逻辑使用。本博文将详细的讲解dubbo的路由相关原理。
一、路由机制原理
Dubbo的路由机制主要解决的目的就是服务调用时,从已知的所有服务提供者中根据路由规则刷选服务提供者。
上图中我们可以看到有两个机房分别是机房A、机房B,其中机房 A 只能访问到 Service A 和 Service B ,而机房B 只能访问到 Service C 和 Service D。要实现上面这种场景我们就需要用到标签路由。从机房 A 发起的调用携带标签 TAG_A 访问到 Service A 和 Service B,而从机房 B 发起的调用携带 TAG_B Service C 和 Service D。
- 提供两个提供者(一台本机作为提供者,一台为其他的服务器),每个提供者会在调用时可以返回不同的信息 以区分提供者。
- 针对于消费者,我们这里通过一个死循环,每次等待用户输入,再进行调用,来模拟真实的请求情况。通过调用的返回值 确认具体的提供者。
- 我们通过ipconfifig来查询到我们的IP地址,并且单独启动一个客户端,来进行如下配置(这里假设我们希望隔离掉本机的请求,都发送到另外一台机器上)。
- 通过这个程序执行后,我们就通过消费端不停的发起请求,看到真实的请求都发到了除去本机以外的另外一台机器上。
1.1 路由规则详解
- route:// 表示路由规则的类型,支持条件路由规则和脚本路由规则,可扩展,必填。
- 0.0.0.0 表示对所有 IP 地址生效,如果只想对某个 IP 的生效,请填入具体 IP,必填。
- com.lagou.service.HelloService 表示只对指定服务生效,必填。
- category=routers 表示该数据为动态配置类型,必填。
- dynamic : 是否为持久数据,当指定服务重启时是否继续生效。必填。
- runtime : 是否在设置规则时自动缓存规则,如果设置为true则会影响部分性能。
- rule : 是整个路由最关键的配置,用于配置路由规则。
1.2 路由机制应用场景
标签路由通过将某一个或多个服务的提供者划分到同一个分组,约束流量只在指定分组中流转,从而实现流量隔离的目的。我们日常工作中常用的场景有:蓝绿发布、灰度发布等场景的能力基础等。我们去想象这样的一个场景,一个dubbo的提供者要准备进行上线,一般都提供多台提供者来同时在线上提供服务。这时候一个请求刚到达一个提供者,提供者却进行了关闭操作。那么此次请求就应该认定为失败了。所以基于这样的场景,我们可以通过路由的规则,把预发布(灰度)的机器进行从机器列表中移除。并且等待一定的时间,让其把现有的请求处理完成之后再进行关闭服务。同时,在启动时,同样需要等待一定的时间,以免因为尚未重启结束,就已经注册上去。等启动到达一定时间之后,再进行开启流量操作。
- 引入 Curator 框架,用于方便操作Zookeeper
- 编写Zookeeper的操作类,用于方便进行zookeeper处理
- 编写需要进行预发布的路径管理器,用于缓存和监听所有的待灰度机器信息列表。
- 编写路由类(实现 org.apache.dubbo.rpc.cluster.Router ),主要目的在于对
- ReadyRestartInstances 中的数据进行处理,并且移除路由调用列表中正在重启中的服务。
- 由于 Router 机制比较特殊,所以需要利用一个专门的 RouterFactory 来生成,原因在于并不是所有的都需要添加路由,所以需要利用 @Activate 来锁定具体哪些服务才需要生成使用。
- 对 RouterFactory 进行注册,同样放入到
- 将dubbo-spi-router项目引入至 consumer 项目的依赖中。
- 这时直接启动程序,还是利用上面中所写好的 consumer 程序进行执行,确认各个 provider 可以正常执行。
- 单独写一个 main 函数来进行将某台实例设置为启动中的状态,比如这里我们认定为当前这台机器中的 service-provider 这个提供者需要进行重启操作。
- 执行完成后,再次进行尝试通过 consumer 进行调用,即可看到当前这台机器没有再发送任何请求
- 一般情况下,当机器重启到一定时间后,我们可以再通过 removeRestartingInstance 方法对这个机器设定为既可以继续执行。
- 调用完成后,我们再次通过 consumer 去调用,即可看到已经再次恢当前机器的请求参数。
二、路由机制源码分析
2.1 RouterChain、RouterFactory 与 Router
- invokers(List
> 类型):当前 RouterChain 对象要过滤的 Invoker 集合。我们可以看到,在 StaticDirectory 中是通过 RouterChain.setInvokers() 方法进行设置的。 - builtinRouters(List
类型):当前 RouterChain 激活的内置 Router 集合。 - routers(List
类型):当前 RouterChain 中真正要使用的 Router 集合,其中不仅包括了上面 builtinRouters 集合中全部的 Router 对象,还包括通过 addRouters() 方法添加的 Router 对象。
在 RouterChain 的构造函数中,会在传入的 URL 参数中查找 router 参数值,并根据该值获取确定激活的 RouterFactory,之后通过 Dubbo SPI 机制加载这些激活的 RouterFactory 对象,由 RouterFactory 创建当前激活的内置 Router 实例,
博文参考
32 路由机制:请求到底怎么走,它说了算(上).md
33 路由机制:请求到底怎么走,它说了算(下).md
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.e1idc.net