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

通过Dubbo3.x标签路由进行流量隔离,第1张

通过Dubbo3.x标签路由进行流量隔离 前言
    《vivo 评论中台的流量及数据隔离实践》中提到流量大的重要业务,提供了单独的集群为其服务,通过Dubbo标签路由方式对整个中台服务集群做了逻辑划分,实现流量隔离的效果
    在上一篇文章《源码学习dubbo3.x的运行期流量调度》接触了Dubbo的路由实现,今天进一步来学习
标签路由规则
    将服务提供者进行分组,约束流量只在指定分组中流转,从而实现流量隔离的目的有两种方式可以完成实例分组,分别是动态规则打标和静态规则打标
    2.1 动态规则相较于静态规则优先级更高
Dubbo Admin动态规则打标
    下载Dubbo Admin的源码(版本为0.4.0)按照官网的方式进行启动
    2.1 因为dubbo-admin-server会将dubbo-admin-ui打包为资源文件,所以启动dubbo-admin-server就可直接访问页面了利用IDEA启动多个provider实例
    3.1 实例demo在dubbo-demo-spring-boot-provider的ProviderApplication
    3.2 IDEA勾选Allow parallel run就可以启动多实例

    3.3 在Dubbo Admin的服务查询页面,选择对应的应用查看详情 点击服务治理 --> 标签路由进行创建
    4.1 点击保存后,将配置发布到ZK的/dubbo/config/dubbo/key.tag-router节点中
Consumer监听标签规则
    标签规则的监听入口: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> 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标签路由
    在dubbo-demo-spring-boot-consumer中调用远程服务时前打上标记,调用指定Provider分组
    标签路由入口:TagStateRouter#route
    2.1 拷贝标签路由规则,防止路由时规则进行了变更
    2.2 获取tag(优先从invocation获取,否则从url中获取<静态打标>)
    2.3 根据规则获取指定tag的provider地址列表,进行过滤排除那些没有的provider(规则的地址和真实注册地址要一致)
    public StateRouterResult> route(BitList> 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 addresses = tagRouterRuleCopy.getTagnameToAddresses().get(tag);
     			// 过滤后result的size=0
     			result = filterInvoker(invokers, invoker -> addressMatches(invoker.getUrl(), addresses));
     		}
    }
    
束语

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

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5718378.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存