写点什么

关于 Dubbo 的原理

用户头像
皮蛋
关注
发布于: 2020 年 12 月 28 日

Dubbo 是阿里巴巴 SOA 服务化治理方案的核心框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,以及 SOA 服务治理方案。其核心部分包含:

  • 远程通讯: 提供对多种基于长连接的 NIO 框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。

  • 集群容错: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。

  • 自动发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。


RPC 工作原理

RPC 的设计由 Client,Client stub,Network ,Server stub,Server 构成。 其中 Client 就是用来调用服务的,Cient stub 是用来把调用的方法和参数序列化的(因为要在网络中传输,必须要把对象转变成字节),Network 用来传输这些信息到 Server stub, Server stub 用来把这些信息反序列化的,Server 就是服务的提供者,最终调用的就是 Server 提供的方法。


  1. Client 像调用本地服务似的调用远程服务;

  2. Client stub 接收到调用后,将方法、参数序列化

  3. 客户端通过 sockets 将消息发送到服务端

  4. Server stub 收到消息后进行解码(将消息对象反序列化)

  5. Server stub 根据解码结果调用本地的服务

  6. 本地服务执行(对于服务端来说是本地执行)并将结果返回给 Server stub

  7. Server stub 将返回结果打包成消息(将结果消息对象序列化)

  8. 服务端通过 sockets 将消息发送到客户端

  9. Client stub 接收到结果消息,并进行解码(将结果消息反序列化)

  10. 客户端得到最终结果。


Dubbo 中服务提供方和服务消费方 RPC 调用调用关系



Dubbo 的总体架构


Dubbo 框架设计一共划分了 10 个层,最上面的 Service 层是留给实际想要使用 Dubbo 开发分布式服务的开发者实现业务逻辑的接口层。图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口, 位于中轴线上的为双方都用到的接口。

下面,结合 Dubbo 官方文档,我们分别理解一下框架分层架构中,各个层次的设计要点:

  1. 服务接口层(Service):该层是与实际业务逻辑相关的,根据服务提供方和服务消费方的业务设计对应的接口和实现。

  2. 配置层(Config):对外配置接口,以 ServiceConfig 和 ReferenceConfig 为中心,可以直接 new 配置类,也可以通过 spring 解析配置生成配置类。

  3. 服务代理层(Proxy):服务接口透明代理,生成服务的客户端 Stub 和服务器端 Skeleton,以 ServiceProxy 为中心,扩展接口为 ProxyFactory。

  4. 服务注册层(Registry):封装服务地址的注册与发现,以服务 URL 为中心,扩展接口为 RegistryFactory、Registry 和 RegistryService。可能没有服务注册中心,此时服务提供方直接暴露服务。

  5. 集群层(Cluster):封装多个提供者的路由及负载均衡,并桥接注册中心,以 Invoker 为中心,扩展接口为 Cluster、Directory、Router 和 LoadBalance。将多个服务提供方组合为一个服务提供方,实现对服务消费方来透明,只需要与一个服务提供方进行交互。

  6. 监控层(Monitor):RPC 调用次数和调用时间监控,以 Statistics 为中心,扩展接口为 MonitorFactory、Monitor 和 MonitorService。

  7. 远程调用层(Protocol):封将 RPC 调用,以 Invocation 和 Result 为中心,扩展接口为 Protocol、Invoker 和 Exporter。Protocol 是服务域,它是 Invoker 暴露和引用的主功能入口,它负责 Invoker 的生命周期管理。Invoker 是实体域,它是 Dubbo 的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起 invoke 调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。

  8. 信息交换层(Exchange):封装请求响应模式,同步转异步,以 Request 和 Response 为中心,扩展接口为 Exchanger、ExchangeChannel、ExchangeClient 和 ExchangeServer。

  9. 网络传输层(Transport):抽象 mina 和 netty 为统一接口,以 Message 为中心,扩展接口为 Channel、Transporter、Client、Server 和 Codec。

  10. 数据序列化层(Serialize):可复用的一些工具,扩展接口为 Serialization、 ObjectInput、ObjectOutput 和 ThreadPool。

根据官方提供的,对于上述各层之间关系的描述,如下所示:

  • 在 RPC 中,Protocol 是核心层,也就是只要有 Protocol + Invoker + Exporter 就可以完成非透明的 RPC 调用,然后在 Invoker 的主过程上 Filter 拦截点。

  • 图中的 Consumer 和 Provider 是抽象概念,只是想让看图者更直观的了解哪些类分属于客户端与服务器端,不用 Client 和 Server 的原因是 Dubbo 在很多场景下都使用 Provider、Consumer、Registry、Monitor 划分逻辑拓普节点,保持统一概念。

  • 而 Cluster 是外围概念,所以 Cluster 的目的是将多个 Invoker 伪装成一个 Invoker,这样其它人只要关注 Protocol 层 Invoker 即可,加上 Cluster 或者去掉 Cluster 对其它层都不会造成影响,因为只有一个提供者时,是不需要 Cluster 的。

  • Proxy 层封装了所有接口的透明化代理,而在其它层都以 Invoker 为中心,只有到了暴露给用户使用时,才用 Proxy 将 Invoker 转成接口,或将接口实现转成 Invoker,也就是去掉 Proxy 层 RPC 是可以 Run 的,只是不那么透明,不那么看起来像调本地服务一样调远程服务。

  • 而 Remoting 实现是 Dubbo 协议的实现,如果你选择 RMI 协议,整个 Remoting 都不会用上,Remoting 内部再划为 Transport 传输层和 Exchange 信息交换层,Transport 层只负责单向消息传输,是对 Mina、Netty、Grizzly 的抽象,它也可以扩展 UDP 传输,而 Exchange 层是在传输层之上封装了 Request-Response 语义。

  • Registry 和 Monitor 实际上不算一层,而是一个独立的节点,只是为了全局概览,用层的方式画在一起。



用户头像

皮蛋

关注

趁着年轻把想实现的实现掉 2019.12.19 加入

又懒又笨

评论

发布
暂无评论
关于Dubbo的原理