前言

本文基于Dubbo2.6.x版本,中文注释版源码已上传github:xiaoguyu/dubbo

今天,来聊点短的,服务路由Router,本文讲的是路由的调用路径,不讲路由的规则解析。想了解规则解析的可以去官方文档:服务路由

Dubbo的路由,就是根据规则,规定了哪些服务消费者可调用哪些服务提供者。

怎么用

我们可以在服务治理控制台Dubbo-Admin写入路由规则。

安装Dubbo-Admin

我是使用docker方式安装的,命令如下:

docker run -d \
-p 9001:8080 \
-e admin.root.user.name=admin \
-e admin.root.user.password=admin \
-e admin.registry.address='zookeeper://127.0.0.1:2181' \
-e admin.config-center='zookeeper://127.0.0.1:2181' \
-e admin.metadata-report.address='zookeeper://127.0.0.1:2181' \
--name dubbo-admin \
apache/dubbo-admin

-e部分的参数说明,看官方介绍Dubbo Admin配置说明

配置规则

浏览器localhost:9001访问Dubbo-Admin控制台,菜单选择 服务治理→条件路由

点击创建按钮,填写相关参数即可

详细参数请参考官方文档:路由规则用法示例

源码

先来看看类图

Router就是路由接口,其有3个实现类。

Router接口有3个方法:

  1. URL getUrl();

  2. List<Invoker> route(List<Invoker> invokers, URL url, Invocation invocation);

    路由的选择方法,筛选出符合条件的invoker

  3. int getPriority();

    获取优先级,用于排序

订阅

当在Dubbo-Admin中配置了路由规则,会在注册中心的routes节点创建子节点,这里就包含了路由配置的数据

上一篇文章讲服务目录的时候,说过RegistryDirectory会订阅providers、consumers、configurators、routers等节点的,这里面就包含了routers

具体的转换逻辑在RegistryDirectory#toRouters方法中

private List<Router> toRouters(List<URL> urls) {
List<Router> routers = new ArrayList<Router>();
if (urls == null || urls.isEmpty()) {
return routers;
}
if (urls != null && !urls.isEmpty()) {
for (URL url : urls) {
if (Constants.EMPTY_PROTOCOL.equals(url.getProtocol())) {
continue;
}
String routerType = url.getParameter(Constants.ROUTER_KEY);
if (routerType != null && routerType.length() > 0) {
url = url.setProtocol(routerType);
}
try {
// 工厂生成route
Router router = routerFactory.getRouter(url);
if (!routers.contains(router))
routers.add(router);
} catch (Throwable t) {
logger.error("convert router url to router error, url: " + url, t);
}
}
}
return routers;
}

routerFactory是自适应拓展类,此处我们设置的是条件路由,所以routerFactory实际上是ConditionRouterFactory

public class ConditionRouterFactory implements RouterFactory {

    public static final String NAME = "condition";

    @Override
public Router getRouter(URL url) {
return new ConditionRouter(url);
} }

这个route工厂也很简单,就是创建了一个ConditionRouter,具体的解析逻辑都在其构造方法中。

规则过滤

路由的核心,就是Router接口的route方法,那么route方法在哪里被引用呢

  1. 服务目录刷新invoker列表时

    当服务目录订阅注册中心信息时,会刷新invoker列表,此时会调用路由

  2. 消费者获取invoker时

    消费者要向生产者发起调用时,依赖的是invoker,此时invoker的获取,需要经过路由筛选

总结

本文讲了服务路由的数据获取以及调用过程。路由的核心就是筛选invoker


参考资料

Dubbo开发指南

Dubbo源码(六) - 服务路由的更多相关文章

  1. Dubbo 源码分析 - 服务调用过程

    注: 本系列文章已捐赠给 Dubbo 社区,你也可以在 Dubbo 官方文档中阅读本系列文章. 1. 简介 在前面的文章中,我们分析了 Dubbo SPI.服务导出与引入.以及集群容错方面的代码.经过 ...

  2. dubbo源码之四——服务发布二

    dubbo版本:2.5.4 2. 服务提供者暴露一个服务的详细过程 上图是服务提供者暴露服务的主过程: 首先ServiceConfig类拿到对外提供服务的实际类ref(如:HelloWorldImpl ...

  3. Dubbo源码学习--服务是如何引用的

    ReferenceBean 跟服务引用一样,Dubbo的reference配置会被转成ReferenceBean类,ReferenceBean实现了InitializingBean接口,直接看afte ...

  4. Dubbo源码学习--服务是如何发布的

    相关文章: Dubbo源码学习--服务是如何发布的 Dubbo源码学习--服务是如何引用的 ServiceBean ServiceBean 实现ApplicationListener接口监听Conte ...

  5. Dubbo源码学习--服务发布(ServiceBean、ServiceConfig)

    前面讲过Dubbo SPI拓展机制,通过ExtensionLoader实现可插拔加载拓展,本节将接着分析Dubbo的服务发布过程. 以源码中dubbo-demo模块作为切入口一步步走进Dubbo源码. ...

  6. Dubbo 源码分析 - 服务引用

    1. 简介 在上一篇文章中,我详细的分析了服务导出的原理.本篇文章我们趁热打铁,继续分析服务引用的原理.在 Dubbo 中,我们可以通过两种方式引用远程服务.第一种是使用服务直联的方式引用服务,第二种 ...

  7. Dubbo 源码分析 - 服务导出

    1.服务导出过程 本篇文章,我们来研究一下 Dubbo 导出服务的过程.Dubbo 服务导出过程始于 Spring 容器发布刷新事件,Dubbo 在接收到事件后,会立即执行服务导出逻辑.整个逻辑大致可 ...

  8. dubbo源码之服务发布与注册

    服务端发布流程: dubbo 是基于 spring 配置来实现服务的发布的,对于dubbo 配置文件中看到的<dubbo:service>等标签都是服务发布的重要配置 ,对于这些提供可配置 ...

  9. dubbo源码之服务消费

    消费端启动初始化过程: 消费端的代码解析也是从配置文件解析开始的,服务发布对应的<dubbo:service,解析xml的时候解析了一个ServiceBean,并且调用ServiceConfig ...

  10. Dubbo源码阅读-服务导出

    Dubbo服务导出过程始于Spring容器发布刷新事件,Dubbo在接收到事件后,会立即执行服务导出逻辑.整个逻辑大致可分为三个部分,第一部分是前置工作,主要用于检查参数,组装URL.第二部分是导出服 ...

随机推荐

  1. 通过VMware的PowerCLI配置集群内指定主机的vMotion功能

    PowerCLI是VMware开发的基于微软(MSFT)的PowerShell的命令行管理vSphere的实现,因此在批量化操作方面CLI会减轻很多GUI环境下的繁琐重复劳作. 现有场景中有大量的物理 ...

  2. FZU 1914 单调队列

    题目链接:http://acm.fzu.edu.cn/problem.php?pid=1914 题意: 给出一个数列,如果它的前i(1<=i<=n)项和都是正的,那么这个数列是正的,问这个 ...

  3. PHP file_get_contents设置超时处理方法

    从PHP5开始,file_get_content已经支持context了(手册上写着:5.0.0 Added the context support. ),也就是说,从5.0开始,file_get_c ...

  4. Android Studio学习随笔-基本事件(点击)

    最常见的点击事件有三种创建方法,在MainActivity.java的onCreate函数(在启动程序是优先运行的程序)中创建setOnClickListener(动态运行)(最常见) protect ...

  5. 笔记整理--C语言

    linux下错误的捕获:errno和strerror的使用 - Google Chrome (2014/2/26 17:31:39) linux下错误的捕获:errno和strerror的使用 201 ...

  6. C# 通过KD树进行距离最近点的查找.

    本文首先介绍Kd-Tree的构造方法,然后介绍Kd-Tree的搜索流程及代码实现,最后给出本人利用C#语言实现的二维KD树代码.这也是我自己动手实现的第一个树形的数据结构.理解上难免会有偏差,敬请各位 ...

  7. 1.7Oob 静态变量静态方法

    1)静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员 2)如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问非静态变量. 3)静态方法中不能直接调用非静态方法 ...

  8. s4-2 ALOHA 协议

    多路访问协议  随机访问协议(Random Access) 特点:站点争用信道,可能出现站点之间的冲突 典型的随机访问协议 • ALOHA协议 • CSMA协议 • CSMA/CD协议(以太网采 ...

  9. LINUX内核分析第六周学习总结——进程的描述和进程的创建

    LINUX内核分析第六周学习总结——进程的描述和进程的创建 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/cours ...

  10. cglib动态代理代码示例

    cglib动态代理代码示例 引用包cglib-xxx.jar 非Maven项目还需要手动引用包asm-xxx.jar 业务类(不需要定义接口) cglib代理类(实现接口MethodIntercept ...