Dubbo源码(六) - 服务路由

打印 上一主题 下一主题

主题 904|帖子 904|积分 2712

前言

本文基于Dubbo2.6.x版本,中文注释版源码已上传github:xiaoguyu/dubbo
今天,来聊点短的,服务路由Router,本文讲的是路由的调用路径,不讲路由的规则解析。想了解规则解析的可以去官方文档:服务路由
Dubbo的路由,就是根据规则,规定了哪些服务消费者可调用哪些服务提供者。
怎么用

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

我是使用docker方式安装的,命令如下:
  1. docker run -d \
  2. -p 9001:8080 \
  3. -e admin.root.user.name=admin \
  4. -e admin.root.user.password=admin \
  5. -e admin.registry.address='zookeeper://127.0.0.1:2181' \
  6. -e admin.config-center='zookeeper://127.0.0.1:2181' \
  7. -e admin.metadata-report.address='zookeeper://127.0.0.1:2181' \
  8. --name dubbo-admin  \
  9. apache/dubbo-admin
复制代码
-e部分的参数说明,看官方介绍Dubbo Admin配置说明
配置规则

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

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

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

先来看看类图

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

  • URL getUrl();
  • List route(List invokers, URL url, Invocation invocation);
    路由的选择方法,筛选出符合条件的invoker
  • int getPriority();
    获取优先级,用于排序
订阅

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

上一篇文章讲服务目录的时候,说过RegistryDirectory会订阅providers、consumers、configurators、routers等节点的,这里面就包含了routers
具体的转换逻辑在RegistryDirectory#toRouters方法中
  1. private List<Router> toRouters(List<URL> urls) {
  2.     List<Router> routers = new ArrayList<Router>();
  3.     if (urls == null || urls.isEmpty()) {
  4.         return routers;
  5.     }
  6.     if (urls != null && !urls.isEmpty()) {
  7.         for (URL url : urls) {
  8.             if (Constants.EMPTY_PROTOCOL.equals(url.getProtocol())) {
  9.                 continue;
  10.             }
  11.             String routerType = url.getParameter(Constants.ROUTER_KEY);
  12.             if (routerType != null && routerType.length() > 0) {
  13.                 url = url.setProtocol(routerType);
  14.             }
  15.             try {
  16.                 // 工厂生成route
  17.                 Router router = routerFactory.getRouter(url);
  18.                 if (!routers.contains(router))
  19.                     routers.add(router);
  20.             } catch (Throwable t) {
  21.                 logger.error("convert router url to router error, url: " + url, t);
  22.             }
  23.         }
  24.     }
  25.     return routers;
  26. }
复制代码
routerFactory是自适应拓展类,此处我们设置的是条件路由,所以routerFactory实际上是ConditionRouterFactory
  1. public class ConditionRouterFactory implements RouterFactory {
  2.     public static final String NAME = "condition";
  3.     @Override
  4.     public Router getRouter(URL url) {
  5.         return new ConditionRouter(url);
  6.     }
  7. }
复制代码
这个route工厂也很简单,就是创建了一个ConditionRouter,具体的解析逻辑都在其构造方法中。
规则过滤

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

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

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

总结

本文讲了服务路由的数据获取以及调用过程。路由的核心就是筛选invoker
参考资料
Dubbo开发指南

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

愛在花開的季節

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表