- 《vivo 评论中台的流量及数据隔离实践》中提到流量大的重要业务,提供了单独的集群为其服务,通过Dubbo标签路由方式对整个中台服务集群做了逻辑划分,实现流量隔离的效果
在上一篇文章《源码学习dubbo3.x的运行期流量调度》接触了Dubbo的路由实现,今天进一步来学习
- 将服务提供者进行分组,约束流量只在指定分组中流转,从而实现流量隔离的目的有两种方式可以完成实例分组,分别是动态规则打标和静态规则打标
2.1 动态规则相较于静态规则优先级更高
- 下载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节点中
- 标签规则的监听入口: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)); } } }
- 在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如何通过标签路由进行流量隔离,并对其中实现进行了分析(不断摩擦,加深理解)
欢迎点赞 收藏 ⭐留言 如有错误敬请指正!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)