通过Dubbo3.x标签路由进行流量隔离

前言

  1. 《vivo 评论中台的流量及数据隔离实践》中提到流量大的重要业务,提供了单独的集群为其服务,通过Dubbo标签路由方式对整个中台服务集群做了逻辑划分,实现流量隔离的效果
    在这里插入图片描述
  2. 在上一篇文章《源码学习dubbo3.x的运行期流量调度》接触了Dubbo的路由实现,今天进一步来学习

标签路由规则

  1. 将服务提供者进行分组,约束流量只在指定分组中流转,从而实现流量隔离的目的
  2. 有两种方式可以完成实例分组,分别是动态规则打标静态规则打标
    2.1 动态规则相较于静态规则优先级更高

Dubbo Admin动态规则打标

  1. 下载Dubbo Admin的源码(版本为0.4.0)
  2. 按照官网的方式进行启动
    2.1 因为dubbo-admin-server会将dubbo-admin-ui打包为资源文件,所以启动dubbo-admin-server就可直接访问页面了
  3. 利用IDEA启动多个provider实例
    3.1 实例demo在dubbo-demo-spring-boot-provider的ProviderApplication
    3.2 IDEA勾选Allow parallel run就可以启动多实例
    在这里插入图片描述
    3.3 在Dubbo Admin的服务查询页面,选择对应的应用查看详情 在这里插入图片描述
  4. 点击服务治理 --> 标签路由进行创建 在这里插入图片描述
    4.1 点击保存后,将配置发布到ZK的/dubbo/config/dubbo/key.tag-router节点中
    在这里插入图片描述

Consumer监听标签规则

  1. 标签规则的监听入口:TagStateRouter#notify
    1.1 取provider的url的application
    1.2 为 /dubbo/config/dubbo/应用名.tag-router节点添加监听器TagStateRouter
    1.3 从节点中获取标签规则
    1.4 触发监听器解析标签规则为TagRouterRule:TagStateRouter#process
    public void notify(BitList<Invoker<T>> invokers) {
        String providerApplication = url.getRemoteApplication();
        synchronized (this) {
        	// 刚开始application为null
        	if (!providerApplication.equals(application)) {
        		// dubbo-springboot-demo-provider.tag-router
        		String key = providerApplication + RULE_SUFFIX;
        		// TreePathDynamicConfiguration#addListener 
        		// pathKey = /dubbo/config/dubbo/dubbo-springboot-demo-provider.tag-router,在pathKey中添加监听器TagStateRouter
        	    this.getRuleRepository().addListener(key, this);
        	    // 添加过就不会再添加
        	    application = providerApplication;
        	    // 从pathKey中获取标签规则
        	    String rawRule = this.getRuleRepository().getRule(key, DynamicConfiguration.DEFAULT_GROUP);
        	    // 触发监听器处理规则
        	    this.process(new ConfigChangedEvent(key, DynamicConfiguration.DEFAULT_GROUP, rawRule));
        	}
        }
    }
    

Consumer标签路由

  1. 在dubbo-demo-spring-boot-consumer中调用远程服务时前打上标记,调用指定Provider分组
    在这里插入图片描述
  2. 标签路由入口:TagStateRouter#route
    2.1 拷贝标签路由规则,防止路由时规则进行了变更
    2.2 获取tag(优先从invocation获取,否则从url中获取<静态打标>)
    2.3 根据规则获取指定tag的provider地址列表,进行过滤排除那些没有的provider(规则的地址和真实注册地址要一致)
    public StateRouterResult<Invoker<T>> route(BitList<Invoker<T>> invokers, URL url,
                                                   Invocation invocation, boolean needToPrintMessage) throws RpcException {
    		// 将标签路由规则进行拷贝,防止变更
    		final TagRouterRule tagRouterRuleCopy = tagRouterRule;
    		// 标签规则不可用处理(暂不分析)
    		if (tagRouterRuleCopy == null || !tagRouterRuleCopy.isValid() || !tagRouterRuleCopy.isEnabled()) {
                return new StateRouterResult<>(filterUsingStaticTag(invokers, url, invocation),
                    needToPrintMessage ? "Disable Tag Router. Reason: tagRouterRule is invalid or disabled" : null);
     		}
    		// 获取tag (RpcInvocation#getAttachment),返回tag1
    		String tag = StringUtils.isEmpty(invocation.getAttachment(TAG_KEY)) ? url.getParameter(TAG_KEY) :
            invocation.getAttachment(TAG_KEY);
     		if (StringUtils.isNotEmpty(tag)) {
     			// 获取规则中指定tag的provider列表(此时size=1)
     			List<String> addresses = tagRouterRuleCopy.getTagnameToAddresses().get(tag);
     			// 过滤后result的size=0
     			result = filterInvoker(invokers, invoker -> addressMatches(invoker.getUrl(), addresses));
     		}
    }
    
    在这里插入图片描述

束语

   本篇文章通过demo实践dubbo如何通过标签路由进行流量隔离,并对其中实现进行了分析(不断摩擦,加深理解)
  📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值