Dubbo的底层实现原理和机制

Dubbo是一个基于RPC的SOA框架,采用NIO异步通讯和单一长连接,适用于小数据量大并发场景。服务提供者启动后注册服务到注册中心,消费者订阅服务并接收变更通知。Netty是一个基于NIO的客户端服务器端编程框架。Dubbo服务暴露分为直接暴露和通过注册中心,消费者通过Invoker转换消费服务。整个流程涉及服务注册、订阅、监控和多种协议实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

总结:Dubbo缺省协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。

Dubbo是基于RPC的SOA框架

作为RPC:支持各种传输协议,如dubbo,hession,json,fastjson,底层采用mina,netty长连接进行传输!典型的provider和cusomer模式!
作为SOA:具有服务治理功能,提供服务的注册和发现!用zookeeper实现注册中心!启动时候服务端会把所有接口注册到注册中心,并且订阅configurators,服务消费端订阅provide,configurators,routers,订阅变更时,zk会推送providers,configuators,routers,启动时注册长连接,进行通讯!proveider和provider启动后,后台启动定时器,发送统计数据到monitor(监控中心)!提供各种容错机制和负载均衡策略!!

我们解释以下这个架构图:https://yq.aliyun.com/articles/38380

为更方便的理解可以看如下图:

Consumer服务消费者,Provider服务提供者。Container服务容器。消费当然是invoke提供者了,invoke这条实线按照图上的说明当然同步的意思了,多说一句,在实际调用过程中,Provider的位置对于Consumer来说是透明的,上一次调用服务的位置(IP地址)和下一次调用服务的位置,是不确定的。这个地方就是实现了软负载。

服务提供者先启动start,然后注册register服务。

消费订阅subscribe服务,如果没有订阅到自己想获得的服务,它会不断的尝试订阅。新的服务注册到注册中心以后,注册中心会将这些服务通过notify到消费者。

Monitor这是一个监控,图中虚线表明Consumer 和Provider通过异步的方式发送消息至Monitor,Consumer和Provider会将信息存放在本地磁盘,平均1min会发送一次信息。Monitor在整个架构中是可选的(图中的虚线并不是可选的意思),Monitor功能需要单独配置,不配置或者配置以后,Monitor挂掉并不会影响服务的调用。

netty 是什么?

“netty 是一个基于nio的客户、服务器端编程框架,netty提供异步的,事件驱动的网络应用程序框架和工具,可以快速开发高可用的客户端和服务器。

netty是基于nio的,它封装了jdk的nio,让我们使用起来更加方法灵活。

二、dubbo原理?

I、初始化过程细节: 
上图中的第一步start,就是将服务装载容器中,然后准备注册服务。和Spring中启动过程类似,spring启动时,将bean装载进容器中的时候,首先要解析bean。所以dubbo也是先读配置文件解析服务。 
解析服务: 
1)、基于dubbo.jar内的Meta-inf/spring.handlers配置,spring在遇到dubbo名称空间时,会回调DubboNamespaceHandler类。 
2)、所有的dubbo标签,都统一用DubboBeanDefinitionParser进行解析,基于一对一属性映射,将XML标签解析为Bean对象。 
在ServiceConfig.export 或者ReferenceConfig.get 初始化时,将Bean对象转会为url格式,将所以Bean属性转成url的参数。 
然后将URL传给Protocol扩展点,基于扩展点的Adaptive机制,根据URL的协议头,进行不同协议的服务暴露和引用。

a、 只暴露服务端口

在没有使用注册中心的情况,这种情况一般适用在开发环境下,服务的调用这和提供在同一个IP上,只需要打开服务的端口即可。 
即,当配置 or 
ServiceConfig解析出的URL的格式为: 
Dubbo://service-host/com.xxx.TxxService?version=1.0.0 
基于扩展点的Adaptiver机制,通过URL的“dubbo://”协议头识别,直接调用DubboProtocol的export()方法,打开服务端口。

b、向注册中心暴露服务:

和上一种的区别:需要将服务的IP和端口一同暴露给注册中心。 
ServiceConfig解析出的url格式为: 
registry://registry-host/com.alibaba.dubbo.registry.RegistryService?export=URL.encode(“dubbo://service-host/com.xxx.TxxService?version=1.0.0”)

基于扩展点的Adaptive机制,通过URL的“registry://”协议头识别,调用RegistryProtocol的export方法,将export参数中的提供者URL先注册到注册中心,再重新传给Protocol扩展点进行暴露: Dubbo://service-host/com.xxx.TxxService?version=1.0.0

四、服务暴露和消费的详细过程

(1)服务提供者暴露一个服务的详细过程

服务提供者暴露服务的主过程:

首先ServiceConfig类拿到对外提供服务的实际类ref(如:HelloWorldImpl),然后通过ProxyFactory类的getInvoker方法使用ref生成一个AbstractProxyInvoker实例,

到这一步就完成具体服务到Invoker的转化。接下来就是Invoker转换到Exporter的过程。

Dubbo处理服务暴露的关键就在Invoker转换到Exporter的过程(如上图中的红色部分),下面我们以Dubbo和RMI这两种典型协议的实现来进行说明:

Dubbo的实现:

Dubbo协议的Invoker转为Exporter发生在DubboProtocol类的export方法,它主要是打开socket侦听服务,并接收客户端发来的各种请求,通讯细节由Dubbo自己实现。

RMI的实现:

RMI协议的Invoker转为Exporter发生在RmiProtocol类的export方法,
它通过Spring或Dubbo或JDK来实现RMI服务,通讯细节这一块由JDK底层来实现,这就省了不少工作量。

(2)服务消费者消费一个服务的详细过程

服务消费的主过程:

首先ReferenceConfig类的init方法调用Protocol的refer方法生成Invoker实例(如上图中的红色部分),这是服务消费的关键。

接下来把Invoker转换为客户端需要的接口(如:HelloWorld)。

那么分布式又是啥?

分布式服务顾名思义服务是分散部署在不同的机器上的,一个服务可能负责几个功能,是一种面向SOA架构的,服务之间也是通过rpc来交互或者是webservice来交互的。逻辑架构设计完后就该做物理架构设计,系统应用部署在超过一台服务器或虚拟机上,且各分开部署的部分彼此通过各种通讯协议交互信息,就可算作分布式部署,生产环境下的微服务肯定是分布式部署的,分布式部署的应用不一定是微服务架构的,比如集群部署,它是把相同应用复制到不同服务器上,但是逻辑功能上还是单体应用。

微服务的区别

微服务相比分布式服务来说,它的粒度更小,服务之间耦合度更低,由于每个微服务都由独立的小团队负责,因此它敏捷性更高,分布式服务最后都会向微服务架构演化,这是一种趋势, 不过服务微服务化后带来的挑战也是显而易见的,例如服务粒度小,数量大,后期运维将会很难

### Dubbo 分布式服务框架的原理与工作机制 Dubbo 是一个高性能、轻量级的开源 Java RPC 框架,旨在提供高效的远程服务调用解决方案,并支持自动化的服务注册与发现功能[^1]。它的设计目标是帮助开发者快速构建分布式服务体系,同时在大规模微服务环境中提供强大的治理能力。 #### 1. Dubbo 的架构概述 Dubbo 的整体架构由多个核心组件构成,这些组件共同协作以完成服务的发布、调用以及管理。以下是其主要组成部分及其作用: - **Provider**: 提供者节点负责暴露服务接口并将其注册到注册中心。 - **Consumer**: 消费者节点通过向注册中心查询来获取可用的服务列表,并发起远程调用请求。 - **Registry**: 注册中心用于存储服务地址信息,充当 Provider Consumer 之间的桥梁。 - **Monitor**: 监控中心记录服务调用次数耗时等指标数据,便于后续分析服务优化。 - **Container**: 容器环境承载着整个 Dubbo 应用程序运行所需的资源支持。 这种分层的设计使得 Dubbo 可以灵活应对不同规模的应用场景需求[^3]。 #### 2. RPC 调用流程详解 RPC (Remote Procedure Call) 即远程过程调用,是一种让客户端像调用本地方法一样访问远端服务器上的某个函数的技术[^2]。具体而言,在 Dubbo实现了一个完整的 RPC 流程如下所示: 1. 当消费者想要调用某项服务时,它会先从配置文件或者动态加载的方式得知该服务对应的 Stub 接口定义; 2. 随后利用代理模式创建出针对此接口的一个实例对象——即所谓的 Client Proxy; 3. 在实际执行过程中,当用户操作这个代理对象的时候,底层便会触发一系列逻辑处理动作,包括但不限于参数序列化打包成字节流形式发送给指定的目标机器; 4. 对方接收到消息之后再经过反序列化解析还原原始输入值交给真正的业务处理器去响应请求最后把结果返回回去同样经历类似的转换步骤直至最终呈现给最初发出指令的一方为止。 下面是简化版伪代码表示这一交互行为: ```java // Service Interface Definition public interface HelloService { String sayHello(String name); } // On the consumer side, create a proxy instance of the service. HelloService helloService = ReferenceConfig.getProxy(HelloService.class); // Invoke remote method as if it were local call. String result = helloService.sayHello("World"); System.out.println(result); // Output: Hello World! ``` 在此期间涉及到的关键技术点还有诸如如何选择合适的连接池大小?怎样设置超时时间防止长时间等待影响用户体验等问题都需要仔细考量才能达到最佳效果[^2]。 #### 3. 核心机制剖析 为了更好地理解 Dubbo 工作机制背后隐藏的秘密,下面重点介绍几个重要方面: ##### (1)通信协议支持 Dubbo 支持多种不同的传输协议,默认采用的是 dubbo:// 方案,这是一种基于 TCP 的私有二进制协议,相比起 HTTP 来说效率更高因为少了大量冗余头部信息开销;当然也允许切换至其他选项比如 hessian:// 或 restful api 形式的 json-rpc 等满足特定场合下的特殊要求。 ##### (2)序列化方式多样性 考虑到跨平台兼容性问题以及性能因素考虑,Dubbo 内置了几种主流的数据编码格式可供挑选例如 fastjson、protobuf 等以便于适应各类复杂度各异的任务负载情况之下均能找到平衡点达成理想状态。 ##### (3)负载均衡算法 为了让流量均匀分布减少单点压力提高系统稳定性,Dubbo 实现了一系列内置策略其中包括随机法(Random LoadBalance),轮询(RoundRobinLoadBalance),最少活跃数(LeastActiveLoadBalance)等等可根据实际情况自由组合运用从而获得最优解路径规划方案。 ##### (4)容错处理机制 面对不可避免的各种异常状况发生可能性,提前做好预案显得尤为重要因此 Dubbo 设计了一套完善的错误恢复体系涵盖重试(Failover Cluster), 忽略失败(Failsafe Cluster), 广播通知(Broadcast Cluster)等多种类型确保即使部分节点出现问题也不会导致全局瘫痪局面出现维持正常运转秩序不变样[^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值