• Dubbo源码(六) - 服务路由


    前言

    本文基于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控制台,菜单选择 服务治理→条件路由

    Untitled

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

    Untitled

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

    源码

    先来看看类图

    Untitled

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

    Router接口有3个方法:

    1. URL getUrl();

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

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

    3. int getPriority();

      获取优先级,用于排序

    订阅

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

    Untitled

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

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

    private List toRouters(List urls) {
    List routers = new ArrayList();
    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列表,此时会调用路由

      Untitled

    2. 消费者获取invoker时

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

      Untitled

    总结

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


    参考资料

    Dubbo开发指南

  • 相关阅读:
    【多模态融合】TransFusion学习笔记(1)
    03路由策略
    宝塔天翼云部署记录
    数聚携手永达汽车集团强势入选爱分析《商业智能实践案例》
    前端性能测试工具WebPagetest
    二十三、java版 SpringCloud分布式微服务云架构之 Java 多态
    [附源码]计算机毕业设计JAVA校园期刊网络投稿系统
    python 实现等声值线图绘制
    工业互联网安全概述
    【解决】多卡服务器GPU不能多用户同时使用的问题
  • 原文地址:https://www.cnblogs.com/konghuanxi/p/16549554.html