Router

简介: 本文深入解析Dubbo集群容错中的Router路由机制,以灰度发布为场景,详解ConditionRouter、ScriptRouter等实现原理。通过实际案例与源码结合,剖析路由如何动态过滤Invoker,分享调试技巧与ZooKeeper节点处理,帮助读者掌握路由在读写分离、应用隔离中的应用,提升对Dubbo架构的深度理解。(238字)

前言
估算了一下,dubbo里面涉及的东西还是比较多的.比如谈到框架的时候,设计模式都是一个老生常谈的话题,再比如我们开发中我们不常用的一些概念,spi、javassist,以及和zookeeper相关的一些知识,比如ZKClient的使用,这些和dubbo关系很密切,但是这些假如我不做一些前戏铺垫就直接把源码贴出来,那真的没啥意义.因为看源码还是要有一些基础,所以我的目标是,即使看不懂源码,但是看我的分析思路和穿插的一些面试题,都能有一些收获.
从标题就知道,这次我讲的是集群容错中的第二个关键词Router,中文意思就是路由,这个路由是个很有意思的词汇.因为前端的路由和后端的路由他们是不同的,但是思想是基本一致的.鉴于很多技术文章都有一个诟病,就是只讲概念,却不讲应用场景,其实Router在应用隔离,读写分离,灰度发布中都有它的影子.因此本篇用灰度发布的例子来做前期的铺垫
灰度发布

先看看百度百科的概念
灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式。AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。

说人话就是,你发布应用的时候,不停止对外的服务,也就是让用户感觉不到你在发布.那么下面演示一下灰度发布。

1.首先在192.168.56.2和192.168.56.3两台机器上启动Provider,然后启动Consumer,如下图

2.假设我们要升级192.168.56.2服务器上的服务,接着我们去dubbo的控制台配置路由,切断192.168.56.2的流量,配置完成并且启动之后,就看到此时只调用192.168.56.3的服务

3.假设此时你在192.168.56.2服务器升级服务,升级完成后再次将启动服务.

4.由于服务已经升级完成,那么我们此时我们要把刚才的禁用路由取消点,于是点了禁用,但是此时dubbo的这个管理平台就出现了bug,如下图所示

惊奇的发现点了禁用,数据就变两条了,继续点禁用,还是两条,而且删除还删除不了,这样就很蛋疼了...但是一直删不了也不是办法,解决办法也是有的,那就是去zookeeper上删除节点。

5.由于我之前是从事iOS开发的,所以一直用的是Mac电脑,Mac上好像没有特别好用的zookeeper可视化客户端工具,于是我就用了这个idea的zookeeper插件,只要将这个zookeeper节点删除

然后刷新控制台的界面,如下图那么就只剩下一条了

6.那么此时我们再看控制台的输出,已经恢复正常,整个灰度发布流程结束

直入主题

我们先来看看Router的继承体系图

从图中可以看出,他有三个实现类,分别是ConditionRouter,MockInvokersSelector,ScriptRouter
MockInvokersSelector在dubbo源码解析-集群容错架构设计中提到这里就暂时不多做叙述。

ScriptRouter在dubbo的测试用例中就有用到,这个类的源码不多,也就124行.引用官网的描述
脚本路由规则 支持 JDK 脚本引擎的所有脚本,比如:javascript, jruby, groovy 等,通过 type=javascript 参数设置脚本类型,缺省为 javascript。
当然看到这里可能你可能还是没有感觉出这个类有什么不可替代的作用,你注意一下这个类中有个ScriptEngine的属性,那么我可以举一个应用场景给你

假如有这么个表达式如下:

double d = (1+1-(2-4)2)/24;//没有问题
"(1+1-(2-4)
2)/24"//但是假如这个表达式是这样的字符串格式,或者更复杂的运算,那么你就不好处理了,然后这个ScriptEngine类的eval方法就能很好处理这类字符串表达式的问题

本篇主要讲讲ConditionRouter(条件路由),条件路由主要就是根据dubbo管理控制台配置的路由规则来过滤相关的invoker,当我们对路由规则点击启用的时候,就会触发RegistryDirectory类的notify方法

其实我觉得看技术类文章更重要的是看分析的思路,看的是思考过程,比如为什么这个notify方法传入的是List呢?如果看过我前两篇dubbo源码解析dubbo源码解析-集群容错架构设计和dubbo源码解析-directory就明白,我的分析过程都是以官方文档为依据,所以这个问题的答案自然也在官方文档.下面引用一段官网文档的描述
所有配置最终都将转换为 URL 表示,并由服务提供方生成,经注册中心传递给消费方,各属性对应 URL 的参数,参见配置项一览表中的 "对应URL参数" 列

其实对于Router来说,我们最关心的就是他是怎么过滤的.所以下面这些流程代码我们先走一遍

这个条件路由有一个特点,就是他的getUrl是有值的,同时这里分享一个IDEA中debug查看表达式内容的技巧,比如router.getUrl()表达式的值,如下图所示

从这里我们看到,此时实现类是ConditionRouter,由于接下来的逻辑如果直接让大家看源码图可能不够清晰,所以我又把这个核心的筛选过程用了一个高清无码图,并且用序号标注

最后的筛选结果如下,因为我们在管理后台配置了禁用192.168.56.2,所以最后添加进invokers的就只有192.168.56.3

相关文章
|
SQL 人工智能 算法
Android性能优化之应用瘦身(APK瘦身)
Android性能优化之应用瘦身(APK瘦身)
|
JavaScript
怎么判断两个文档节点、网页元素(element)是否相同?判断两个DOM节点是否相等、相同的4种方法
怎么判断两个文档节点、网页元素(element)是否相同?判断两个DOM节点是否相等、相同的4种方法
|
Ubuntu 安全 关系型数据库
window下的子系统ubuntu 运行docker遇到的坑
<p>  1.启动mysql容器后,使用docker ps 查看时是没有启动起来 ,使用docker logs 容器id 时,查看报错信息如下:</p> <p>  mysql_ssl_rsa_setup: Can't change permissions of the file 'ca-key.pem' (Errcode: 1 - Operation not permitted)</p> <p>  2021-06-27 11:56:04 [ERROR] Error setting file permissions forca-key.pem and ca.pem</p>
3203 0
|
传感器 监控 安全
|
5月前
|
人工智能 自然语言处理 Cloud Native
大模型应用落地实战:从Clawdbot到实在Agent,如何构建企业级自动化闭环?
2026年初,开源AI Agent Clawdbot爆火,以“自由意志”打破被动交互,寄生社交软件主动服务。它解决“听与说”,却缺“手与脚”:硅谷Manus走API原生路线,云端自主执行;中国实在Agent则用屏幕语义理解,在封闭系统中精准操作。三者协同,正构建AI真正干活的三位一体生态。
3428 11
|
6月前
|
JSON 安全 JavaScript
HTTPS 原理
HTTPS是HTTP与SSL/TLS的结合,通过数字证书验证身份,利用非对称加密安全交换会话密钥,再以对称加密高效传输数据。它确保了通信的机密性、完整性和服务器真实性,在互联网上构建安全加密通道。
|
7月前
|
JSON 安全 JavaScript
深入浅出解析 HTTPS 原理
HTTPS是HTTP与SSL/TLS结合的安全协议,通过数字证书验证身份,利用非对称加密安全交换会话密钥,再以对称加密高效传输数据,确保通信的机密性、完整性和真实性。整个过程如同建立一条加密隧道,保障网络交互安全。
2657 16
|
6月前
|
Java Spring
GateWay实现原理
Spring Cloud Gateway基于Spring WebFlux与Netty,实现高性能非阻塞通信。启动时创建Netty Server接收客户端请求,经路由匹配与过滤器处理后,由Netty Client转发至目标服务,响应反向经过滤器处理后返回,全程非阻塞,提升系统吞吐能力。(238字)
|
6月前
|
机器学习/深度学习 人工智能 算法
让AI真正读懂长文本的秘密武器
通义实验室推出QwenLong-L1.5,基于Qwen3-30B-A3B打造的长文本推理专家。通过高质量多跳数据合成、稳定强化学习算法与突破窗口限制的记忆框架,系统性解决长文本“学不好、用不了”难题,在多跳推理、超长上下文等任务中媲美GPT-5与Gemini。
|
6月前
|
消息中间件 Java 数据格式
微服务核心组件:消息中间件(MQ)从入门到实战
本章深入讲解微服务中消息中间件的核心作用,聚焦RabbitMQ与SpringAMQP实战。涵盖同步与异步通信对比、MQ选型分析,通过Docker快速部署RabbitMQ,详解生产者/消费者模型、四种消息模式(简单队列、工作队列、发布订阅、通配符路由),并引入prefetch优化与JSON序列化提升性能。结合注解驱动开发,全面掌握高可用、低耦合的异步通信架构设计。(239字)