欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

1 | Dubbo:探讨标签路由的实现

程序员文章站 2022-04-29 23:25:34
...

1 | Dubbo:探讨标签路由的实现

对 Dubbo 进行了一次功能调研,主要集中在服务治理中的标签路由。这部分的内容不难,但是能够对 Dubbo 的实现有一定的了解。

环境搭建

需要 ZooKeeper、Java Application Based on Dubbo。

ZooKeeper 的搭建

通过 CODING CD,在腾讯云的弹性伸缩组上(有兴趣可到 CODING CD 中详细了解),部署的一个实例,需要先安装 java 依赖,如下:

java-1.8.0-openjdk-devel.x86_64

其主要的配置是一个脚本,如下:

wget http://mirrors.hust.edu.cn/apache/zookeeper/zookeeper-3.6.1/apache-zookeeper-3.6.1-bin.tar.gz
tar -xzvf apache-zookeeper-3.6.1-bin.tar.gz
mv apache-zookeeper-3.6.1-bin zk
mv zk/conf/zoo_sample.cfg zk/conf/zoo.cfg

echo '''[Unit]
Description=ZooKeeper for Dubbo 
After=network.target
[Service]
Type=forking
ExecStart=/bin/sh /root/zk/bin/zkServer.sh start
ExecStop=/bin/sh /root/zk/bin/zkServer.sh stop
User=root
[Install]
WantedBy=multi-user.target ''' > /usr/lib/systemd/system/zk-for-dubbo.service
systemctl enable zk-for-dubbo

在安全组中确保端口 2181 开放。此时:

  • 公网 IP 为 49.233.238.170
  • 内网 IP 为 172.21.0.34

Java Application Based on Dubbo

A 模块在调用 B 模块前,设置了一个 TAG_KEY,表示选择带有 TAG_KEY 的 B 服务:

@Reference
private DoSomeThingService doSomeThingService;

public String sayHello() {
    RpcContext.getContext().setAttachment(CommonConstants.TAG_KEY, "tag1");
    return doSomeThingService.sayHello();
}

应用的部署还是采用 CODING CD 部署在腾讯云的弹性伸缩组上。主要的配置如下:

A 模块启动:

java -jar -Ddubbo.registry.address=zookeeper://172.21.0.34:2181 /root/a.jar 2>&1 &

B 模块启动:

java -jar -Ddubbo.registry.address=zookeeper://172.21.0.34:2181 /root/b.jar 2>&1 &

Dubbo admin 安装与配置

dubbo-admin 使用的 github 中 develop 的最新版,按照相应的提示进行构建即可。

启动 dubbo-admin 的前端,此时的目录为 dubbo-admin/dubbo-admin-ui

npm run dev

启动 dubbo-admin 的后端,此时的目录为 dubbo-admin/dubbo-admin-server

修改 dubbo-admin/dubbo-admin-server/src/main/resources/application.properties 文件,改成正确的 zookeeper 地址。

admin.registry.address=zookeeper://49.233.238.170:2181
admin.config-center=zookeeper://49.233.238.170:2181
admin.metadata-report.address=zookeeper://49.233.238.170:2181

编译并启动

mvn clean package -DskipTests=true
cd target
java -jar dubbo-admin-server-0.2.0-SNAPSHOT.jar

打开 dubbo-admin,找到标签路由,配置如下,应用名填写 moduleb:

enabled: true
force: true
runtime: true
tags:
  - name: tag1
    addresses:
      - '172.21.0.40:20880'
  - name: tag2
    addresses: null

TIPS
如果有遇到在 Dubbo Admin 中修改不生效的情况,考虑一下 Dubbo Admin 与 Dubbo 版本间的差异。在此踩到一个坑如下:

Dubbo Admin 管理页面是用 docker 跑起来的,它里面的源代码比较旧,路由设置到 zk 中的路径与 dubbo 读取 zk 的路径不一样。ISSUE 可见:https://github.com/apache/dubbo-admin/issues/577

效果展示

请求流向:LB -> A -> B

A 中设置的 TAG_KEY 为:

public String sayHello() {
    RpcContext.getContext().setAttachment(CommonConstants.TAG_KEY, "tag1");
    return doSomeThingService.sayHello();
}

此时 B 模块服务有两个,即一个新、一个旧。
1 | Dubbo:探讨标签路由的实现

如果要只返回最新版本,可在 dubbo-admin 控制台的服务治理中,添加标签路由,新的实例在 tag1 下,旧的实例在 tag2 下,如下:

enabled: true
force: true
runtime: true
tags:
  - name: tag1
    addresses:
      - '172.21.0.21:20880'
  - name: tag2
    addresses:
      - '172.21.0.40:20880'

此时的返回如下:
1 | Dubbo:探讨标签路由的实现

如果只使用旧版本实例,可在将上面 tag1 和 tag2 下面的内容调换即可,此时返回如下:
1 | Dubbo:探讨标签路由的实现

如果要同时能够访问到新旧实例的内容,将上述配置中所有的 IP 全部填写到 tag1 下即可,此时的返回如下:
1 | Dubbo:探讨标签路由的实现

Dubbo 标签路由的实现原理

总共分三个大的方面,分别是配置的存储、配置同步、如何解析配置。

标签路由配置的存储

URL: /api/dev/rules/route/tag/moduleb
Request Method: PUT

在 dubbo-admin-server 中它的实现在文件 TagRoutesController.java 中,最终是将配置保存到 ZooKeeper 中,保存的路径为:
1 | Dubbo:探讨标签路由的实现

即:/dubbo/config/dubbo/moduleb.tag-router

在 ZooKeeper 中可以在相应的路径下看到相关的配置,如下:
1 | Dubbo:探讨标签路由的实现

配置变更同步

TagRouter.java 中实现了 ConfigurationListener 接口,当配置变更时,会更新 tagRouterRule

@Override
public synchronized void process(ConfigChangedEvent event) {
    if (logger.isDebugEnabled()) {
        logger.debug("Notification of tag rule, change type is: " + event.getChangeType() + ", raw rule is:\n " +
                event.getContent());
    }

    try {
        if (event.getChangeType().equals(ConfigChangeType.DELETED)) {
            this.tagRouterRule = null;
        } else {
            this.tagRouterRule = TagRuleParser.parse(event.getContent());
        }
    } catch (Exception e) {
        logger.error("Failed to parse the raw tag router rule and it will not take effect, please check if the " +
                "rule matches with the template, the raw rule is:\n ", e);
    }
}

配置解析

源码位于 dubbo 中的 TagRouter.java
1 | Dubbo:探讨标签路由的实现

结语

在上面的示例中,我们需要手动在 dubbo-admin 界面中,新增标签路由的配置,但经过对该配置的新增过程的简要分析,发现只是在 ZooKeeper 中新增一条记录。

1 | Dubbo:探讨标签路由的实现