首页 > 其他分享 >Dubbo——路由(Router)规则原理

Dubbo——路由(Router)规则原理

时间:2023-03-21 10:38:30浏览次数:37  
标签:Dubbo 请求 提供者 RouterFactory TAG Router 路由


摘要

Router 的主要功能就是根据用户配置的路由规则以及请求携带的信息,过滤出符合条件的 Invoker 集合,供后续负载均衡逻辑使用。本博文将详细的讲解dubbo的路由相关原理。

一、路由机制原理

Dubbo的路由机制主要解决的目的就是服务调用时,从已知的所有服务提供者中根据路由规则刷选服务提供者。

Dubbo——路由(Router)规则原理_List

# demo-provider 应用增加了两个标签分组 TAG_A 和 TAG_B
# TAG_A 包含一个实例 127.0.0.1:20880
# TAG_B 包含一个实例 127.0.0.1:20881
force: true
enabled: true
runtime: false
tags:
- name: TAG_A
addresses: [192.168.0.1:20880]
- name: TAG_B
addresses: [192.168.0.2:20881]

上图中我们可以看到有两个机房分别是机房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的提供者要准备进行上线,一般都提供多台提供者来同时在线上提供服务。这时候一个请求刚到达一个提供者,提供者却进行了关闭操作。那么此次请求就应该认定为失败了。所以基于这样的场景,我们可以通过路由的规则,把预发布(灰度)的机器进行从机器列表中移除。并且等待一定的时间,让其把现有的请求处理完成之后再进行关闭服务。同时,在启动时,同样需要等待一定的时间,以免因为尚未重启结束,就已经注册上去。等启动到达一定时间之后,再进行开启流量操作。

1.利用zookeeper的路径感知能力,在服务准备进行重启之前将当前机器的IP地址和应用名写入 zookeeper。 
2.服务消费者监听该目录,读取其中需要进行关闭的应用名和机器IP列表并且保存到内存中。
3.当前请求过来时,判断是否是请求该应用,如果是请求重启应用,则将该提供者从服务列表中移除。
  • 引入 Curator 框架,用于方便操作Zookeeper
  • 编写Zookeeper的操作类,用于方便进行zookeeper处理
  • 编写需要进行预发布的路径管理器,用于缓存和监听所有的待灰度机器信息列表。
  • 编写路由类(实现 org.apache.dubbo.rpc.cluster.Router ),主要目的在于对
  • ReadyRestartInstances 中的数据进行处理,并且移除路由调用列表中正在重启中的服务。
  • 由于 Router 机制比较特殊,所以需要利用一个专门的 RouterFactory 来生成,原因在于并不是所有的都需要添加路由,所以需要利用 @Activate 来锁定具体哪些服务才需要生成使用。

Dubbo——路由(Router)规则原理_IP_02

  • 对 RouterFactory 进行注册,同样放入到
META-INF/dubbo/org.apache.dubbo.rpc.cluster.RouterFactory 文件中。
restartInstances=com.lagou.router.RestartingInstanceRouterFactory
  • 将dubbo-spi-router项目引入至 consumer 项目的依赖中。
  • 这时直接启动程序,还是利用上面中所写好的 consumer 程序进行执行,确认各个 provider 可以正常执行。
  • 单独写一个 main 函数来进行将某台实例设置为启动中的状态,比如这里我们认定为当前这台机器中的 service-provider 这个提供者需要进行重启操作。
ReadyRestartInstances.create().addRestartingInstance("service-provider", "正在 
重新启动的机器IP");
  • 执行完成后,再次进行尝试通过 consumer 进行调用,即可看到当前这台机器没有再发送任何请求
  • 一般情况下,当机器重启到一定时间后,我们可以再通过 removeRestartingInstance 方法对这个机器设定为既可以继续执行。
  • 调用完成后,我们再次通过 consumer 去调用,即可看到已经再次恢当前机器的请求参数。

二、路由机制源码分析

Dubbo——路由(Router)规则原理_IP_03

2.1 RouterChain、RouterFactory 与 Router

  • invokers(List<Invoker​​<T>​​> 类型):当前 RouterChain 对象要过滤的 Invoker 集合。我们可以看到,在 StaticDirectory 中是通过 RouterChain.setInvokers() 方法进行设置的。
  • builtinRouters(List​​<Router>​​ 类型):当前 RouterChain 激活的内置 Router 集合。
  • routers(List​​<Router>​​ 类型):当前 RouterChain 中真正要使用的 Router 集合,其中不仅包括了上面 builtinRouters 集合中全部的 Router 对象,还包括通过 addRouters() 方法添加的 Router 对象。

在 RouterChain 的构造函数中,会在传入的 URL 参数中查找 router 参数值,并根据该值获取确定激活的 RouterFactory,之后通过 Dubbo SPI 机制加载这些激活的 RouterFactory 对象,由 RouterFactory 创建当前激活的内置 Router 实例,

private RouterChain(URL url) {

// 通过ExtensionLoader加载激活的RouterFactory

List<RouterFactory> extensionFactories = ExtensionLoader.getExtensionLoader(RouterFactory.class)

.getActivateExtension(url, "router");

// 遍历所有RouterFactory,调用其getRouter()方法创建相应的Router对象

List<Router> routers = extensionFactories.stream()

.map(factory -> factory.getRouter(url))

.collect(Collectors.toList());

initWithRouters(routers); // 初始化buildinRouters字段以及routers字段

}

public void initWithRouters(List<Router> builtinRouters) {

this.builtinRouters = builtinRouters;

this.routers = new ArrayList<>(builtinRouters);

this.sort(); // 这里会对routers集合进行排序

}

博文参考

​32 路由机制:请求到底怎么走,它说了算(上).md​

​33 路由机制:请求到底怎么走,它说了算(下).md​

标签:Dubbo,请求,提供者,RouterFactory,TAG,Router,路由
From: https://blog.51cto.com/u_13643065/6139634

相关文章

  • Dubbo——集群(Cluster)容错原理
    摘要集群中的单个节点有一定概率出现一些问题,例如,磁盘损坏、系统崩溃等,导致节点无法对外提供服务,因此在分布式RPC框架中,必须要重视这种情况。为了避免单点故障,我们的Prov......
  • Dubbo——本地缓存和重试机制原理
    摘要本地缓存机制:作为一个RPC框架,在网络抖动等原因而导致订阅失败时,Consumer能够调用本地缓存提供的可用的URL消费者,保证了服务的可靠性。重试机制”就是在请求失败时,客户......
  • 动态路由之RIP协议和OSPF协议
    一.概述路由信息协议RIP(RoutingInformationProtocol)是基于距离矢量算法的路由协议,利用跳数来作为计量标准。rip协议最初被开发出来的时候并没有考虑到带宽的因素,因为在......
  • 计讯物联工业路由器基于5G LAN技术成为工业互联网发展的“加速器”
    随着5G的成熟发展,其易部署、低时延、高可靠、大带宽、广连接的特性助力传统工业智能数字化转型,解决了传统工业的布线繁琐、通信环境复杂易造成干扰、对时延与稳定性更加敏......
  • vue+element-ui刷新路由的时候保持在当前页面小技巧
    前言:很多小伙伴在练习vue项目的时候会遇到这样一个问题,就是刷新页面的时候,路由没有显示到当前页面,而是重定向回首页了,那么该怎么解决呢,就请各位小伙伴看下面的内容介绍吧......
  • 网络系统管理Linux环境——7.ROUTERSRV之IPTABLES
    题目要求服务器RouterSrv上的工作任务6. IPTABLES添加必要的网络地址转换规则,使外部客户端能够访问到内部服务器上的dns、mail、web和ftp服务。INPUT、OUTPUT和FOREARD链......
  • 网络系统管理Linux环境——4.ROUTERSRV之SSH
    题目要求服务器RouterSrv上的工作任务3. SSH工作端口为2021;只允许用户user01,密码ChinaSkill21登录到router。其他用户(包括root)不能登录,创建一个新用户,新用户可以从本地登......
  • 网络系统管理Linux环境——5.ROUTERSRV之NTP
    题目要求服务器RouterSrv上的工作任务4. NTP在ISPSRV作为时间服务器安装chrony,提供时间同步。在AppSrv和StorageSrv创建CRON计划任务,每隔五分钟进行一次时间同步。项目实......
  • 网络系统管理Linux环境——6.ROUTERSRV之OPEN为皮N
    题目要求服务器RouterSrv上的工作任务5. OPENVPNVPN客户端只能与InsideCli客户端网段通信,以及允许访问StorageSrv主机上的SAMBA服务;VPN客户端可使用的地址范围是172.16.0......
  • Dubbo的整体架构设计及分层
    五个角色:注册中心registry:服务注册与发现服务提供者provider:暴露服务服务消费者consumer:调用远程服务监控中心monitor:统计服务的调用次数和调用时间容器container:服务......