源码学习dubbo3.x的运行期流量调度

Dubbo3.x流量调度
本文剖析了Dubbo3.x的运行期流量调度机制,详细介绍了如何通过配置路由规则实现灰度发布等功能,并探讨了其内部实现原理。

前言

  1. dubbo官网可知Dubbo提供了六大核心能力,运行期流量调度就是其中一种。
  2. 运行期流量调度:内置条件、脚本等路由策略,通过配置不同的路由规则,轻松实现灰度发布,同机房优先等功能。
  3. 下面我们通过源码调式探索,运行期流量调度是怎样实现的?

Dubbo如何触发路由规则

  1. 通过前面描述可知,运行期流量调度时通过配置路由规则实现的
  2. 具体如何配置路由规则,参照官网《路由规则》说明
    2.1 路由规则包括入站流量的规则(VirtualService)和目标地址规则(DestinationRule)
  3. 通过《dubbo3.x消费端源码浅析以及Triple协议的实现》文章中了解到Dubbo远程调用主要步骤如下
    // AbstractClusterInvoker#invoke
    public Result invoke(final Invocation invocation) throws RpcException {
    	// 根据调用信息获取Invoker列表(通过流量规则进行路由选择)
    	List<Invoker<T>> invokers = list(invocation);
    	// 在Invoker列表中进行负载
    	LoadBalance loadbalance = initLoadBalance(invokers, invocation);
    	return doInvoke(invocation, invokers, loadbalance);
    }
    

路由规则过滤

  1. 路由规则过滤调用栈入口如下
    在这里插入图片描述
  2. 主要关注MeshRuleRouter#route
    2.1 在dubbo源码中没有找到相应的配置demo,但是有MeshRuleRouter的测试类MeshRuleRouterTest,我们就跑一下测试用例(route方法)了解其内部运行机制
    public <T> RouterResult<Invoker<T>> route(List<Invoker<T>> invokers, URL url,
                                              Invocation invocation, boolean needToPrintMessage) throws RpcException {
         // 根据调用信息(服务名、方法)获取具体的流量规则列表
    	List<DubboRouteDestination> routeDestination = getDubboRouteDestination(invocation);
    	// 如果没配入口流量规则或者不匹配,则返回全部的invoker
    	if (routeDestination == null) {
            return new RouterResult<>(invokers);
        }else{
        	// 随机选择一个入口流量规则
    		DubboRouteDestination dubboRouteDestination = routeDestination.get(ThreadLocalRandom.current().nextInt(routeDestination.size()));
    		// DubboDestination:用来描述路由流量的目标地址
    		DubboDestination dubboDestination = dubboRouteDestination.getDestination();
    		// subset :地址列表
    		String subset = dubboDestination.getSubset();
    		
    		List<Invoker<?>> result;
    		Map<String, List<Invoker<?>>> subsetMapCopy = this.subsetMap;
    		do {
    			// 获取地址列表对应的Invoker列表(subsetMapCopy内容是根据目标地址规则匹配出来的)
    			result = subsetMapCopy.get(subset);
    			if (CollectionUtils.isNotEmpty(result)) {
                  	return new RouterResult<>((List) result);
               	}
               	/**
               	  * fallback 处理原则(摘抄于官网描述)
               	  * 由于多个 router 之间多个条件组件之后,很容易出现地址被筛选为空的情	
               	  * 况,那么我们需要针对这情况进行 fallback 处理,保证业务在正确性的前提
               	  * 下,能够顺利找到有效地址
               	  * */
               	dubboRouteDestination = dubboDestination.getFallback();
                if (dubboRouteDestination == null) {
                    break;
                }
                dubboDestination = dubboRouteDestination.getDestination();
                subset = dubboDestination.getSubset();
    		}while(true)
    		
    	}
    }
    
    2.2 跟了流量规则路由的代码后,总结一下
    (1)根据调用信息的服务名方法信息匹配符合条件的流量的实际目标地址(入站流量的规则)
    (2)根据配置的服务标签匹配符合条件的服务参数的invoker列表(目标地址规则)
    (3)入站流量规则的spec.dubbo.routedetail.route.destination.subnet与目标地址规则的spec.subsets.name一一对应,找到符合的invoker列表

灰度发布

  1. 什么是灰度发布?
    1.1 百度百科的解释:灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式。在其上可以进行A/B testing,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度

  2. Dubbo对灰度的支持
    2.1 实现灰度发布,在请求到达服务提供前,能将请求按预设的规则去访问目标服务提供者
    2.2 通过上面可知,invocaruib会先经过一个路由器链并返回一组合适的目标服务器地址列表,然后在这些服务器地址中做负载均衡

束语

  1. 本篇文章主要分析Dubbo3.x的路由规则,了解其内部是如何路由选择的。
  2. 了解灰度发布的概念,知道Dubbo3.x是如何支持灰度发布的
  3. 突然发现标题写的是运行期流量调度,那怎样运行时修改调度规则呢?
    3.1 在跟代码时发现,在启动时会初始化MeshAppRuleListener
    3.2 MeshAppRuleListener的process处理数据变更
<think>好的,我现在需要回答用户关于Dubbo 3.x与Hessian的关系及使用方法,以及兼容性分析的问题。首先,我得回忆一下Dubbo和Hessian的基本概念。Dubbo是一个高性能的Java RPC框架,而Hessian是一种基于HTTP的二进制序列化协议,常用于远程服务调用。用户可能想知道在Dubbo 3.x中如何支持Hessian协议,以及升级时的兼容性问题。 接下来,我需要查阅提供的引用内容。引用[3]提到了在Spring Boot中整合Dubbo 2.6并支持Hessian双协议,说明Hessian在Dubbo中的使用需要配置协议,并且有公共接口模块。引用[1]和[2]讨论了Dubbo 3.x的优势和升级建议,但没有直接提到Hessian。引用[4]涉及Dubbo 3.x的源码,可能涉及协议处理部分,但具体细节需要推断。 首先,Hessian在Dubbo中通常作为一种序列化协议或RPC协议使用。Dubbo支持多协议,比如默认的Dubbo协议,以及Hessian、HTTP等。在Dubbo 3.x中,是否继续支持Hessian?根据Dubbo的文档,3.x版本仍然支持扩展协议,所以Hessian应该可用,但可能需要检查配置方式是否有变化。 关于使用方法,用户可能需要知道如何在Dubbo 3.x中配置Hessian协议。例如,在服务提供者和消费者的XML或注解配置中指定协议为hessian,并确保相关依赖(如dubbo-rpc-hessian)被正确引入。同时,需要注意接口的兼容性,尤其是在服务提供者和消费者之间共享的API模块,可能需要使用相同的序列化方式。 兼容性分析方面,用户从Dubbo 2.x升级到3.x时,如果之前使用了Hessian协议,需要确认Dubbo 3.x是否保持了Hessian协议的兼容性。根据引用[1],Dubbo 3.x增强了互操作性,但可能对某些模块进行了优化或调整。因此,需要检查是否有配置变更或依赖更新的要求,例如新的Maven依赖或配置属性。 另外,Hessian协议本身的不同版本(如Hessian2)可能会有差异,需要确保Dubbo 3.x使用的Hessian版本与客户端兼容。此外,序列化过程中的类结构变化可能导致问题,因此建议保持接口模块的稳定性,并充分测试。 可能还需要考虑Dubbo 3.x的新特性,如应用级服务发现,是否影响Hessian协议的使用。例如,服务注册和发现机制的变化可能不影响协议本身,但需要确保服务暴露和引用时正确配置协议类型。 总结来说,回答应包括Hessian在Dubbo 3.x中的配置步骤、依赖管理、接口共享注意事项,以及升级时的兼容性检查点,如依赖版本、配置语法、序列化兼容性等。同时,建议用户参考官方文档和进行测试以确保平滑过渡。</think>### Dubbo 3.x 与 Hessian 的关系及使用说明 #### 1. **Hessian 在 Dubbo 中的角色** Hessian 是一种基于 HTTP 的二进制序列化协议,常用于跨语言、轻量级的远程调用。在 Dubbo 中,Hessian 可作为 RPC 协议或序列化方式使用: - **协议支持**:Dubbo 默认使用 `dubbo` 协议,但支持扩展其他协议(如 `hessian`),通过配置即可切换[^3]。 - **序列化兼容性**:Hessian 的序列化方式对接口类结构敏感,需确保服务提供方和消费方的接口定义完全一致。 #### 2. **Dubbo 3.x 中配置 Hessian 协议** 在 Dubbo 3.x 中使用 Hessian 协议需以下步骤: 1. **添加依赖**:引入 `dubbo-rpc-hessian` 模块。 ```xml <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-rpc-hessian</artifactId> <version>3.x.x</version> </dependency> ``` 2. **配置协议**:在服务提供方和消费方的配置文件中声明 Hessian 协议。 ```xml <!-- 服务提供方 --> <dubbo:protocol name="hessian" port="8080" server="jetty"/> <!-- 服务消费方 --> <dubbo:reference protocol="hessian" ... /> ``` 3. **接口模块化**:将服务接口抽离为独立模块(如 `dubbo-api`),供提供方和消费方共用[^3]。 #### 3. **兼容性分析** - **Dubbo 版本兼容性**: Dubbo 3.x 保留了与 2.x 的协议兼容性,但需注意以下差异: - **依赖升级**:Dubbo 3.x 的 `dubbo-rpc-hessian` 可能依赖更新的 Hessian 版本(如 Hessian4),需验证序列化兼容性。 - **配置语法**:Dubbo 3.x 强化了云原生支持,但协议配置方式与 2.x 基本一致[^1][^4]。 - **Hessian 协议限制**: - **类结构一致性**:若接口类增加/删除字段,需同步升级所有依赖方,否则会因序列化失败导致调用异常。 - **性能对比**:Hessian 协议性能低于 Dubbo 默认协议,适合对协议通用性要求高、性能非关键的场景。 #### 4. **升级建议** - **渐进式升级**:从 Dubbo 2.7.x 升级到 3.x 时,可先验证 Hessian 协议在混合环境中的表现[^2]。 - **测试验证**:通过单元测试和集成测试检查序列化/反序列化逻辑,尤其是涉及复杂对象传输的场景。 - **替代方案**:若需高性能,可考虑使用 Dubbo 3.x 的 Triple 协议(基于 HTTP/2 + gRPC),同时支持跨语言和更高效的序列化。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值