Dubbo 底层原理剖析

开篇

本文会通过 图文 + 案例,对 Dubbo 的底层原理进行剖析 – 探索 Dubbo 分层的意义。

阅读之前,要求对 Dubbo 有所了解,并且会简单使用。

正文

先来看一张摘自官网的 令人头大Dubbo 框架设计图,除此之外还有几张图,这里就不一一贴出了,详细请参考 Dubbo 框架设计

在这里插入图片描述

其实 Dubbo 官网关于框架设计的部分已经讲得很详细了,但是对于类似我这样道行不深的菜鸟, 短时间内还是无法快速理解。

框架设计的简要说明

Dubbo 的框架设计图中从下至上分为十层,其中,ServiceConfig 层为 API,其它各层均为 SPI。也就是除了 ServiceConfig 层,其余各层都至少有一种替代品。

比如 Protocol 层:

  • org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol
  • org.apache.dubbo.rpc.protocol.rmi.RmiProtocol
  • org.apache.dubbo.rpc.protocol.http.HttpProtocol

Dubbo 的这种高扩展性全部基于 Dubbo SPI 机制,该机制是研究 Dubbo 源码的关键和基础。

官网 Demo 案例

篇幅原因,具体使用方法和代码还是到官网 Dubbo – 快速启动,下面的内容全部基于这个案例。

图解服务调用过程

官网给出了非常详细的 服务调用过程,但都是从架构层面,还有整个流程会经历哪个类,哪个方法,下面就基于官网的图文,再结合案例给出自己的理解。

从 main 函数的代码来看,整个流程看着很简单

在这里插入图片描述

当我们加上注册中心后

结合 xml 配置 和 Dubbo – 架构, 图解如下:

在这里插入图片描述

结合框架设计

在这里插入图片描述

服务引用过程

  • 4.1 Proxy 层

对服务消费端使用的 DemoService接口进行代理,把本地调用透明地转换为远程调用, 该层默认使用的是 JavassistProxyFactory, 对该层的理解,可以参考之前的文章 基于 Java 实现最初级版的 RPC

  • 4.2 Cluster 层

从图中可以看出,服务提供者有 2 个实例,那么消费者最终会调用哪个实例,就是由 Cluster 层决定的,该层还会桥连注册中心 zookeeper,获取 2 个服务提供者的注册信息,比如ip,port。当然该层还有其他功能。

  • 4.3 Protocol 层

要实现图中的远程调用,其实本质就是通过网络通信,来传输信息。Dubbo 为此提供了多种通信协议,默认为 DubboProtocol。

// 有删减
dubbo://LOCALHOST:20880/org.apache.dubbo.demo.DemoService
?anyhost=true&application=demo-provider&bind.ip=192.168.31.87&bind.port=20880&
interface=org.apache.dubbo.demo.DemoService
&methods=sayHello,sayHello1&timestamp=1586693904645
复制代码
  • 4.4 Exchanger 层

封装请求响应内容为 Request / Response 对象。做 web 接口开发的都知道,我们会把一些参数或者响应内容封装到 XXXRequest/YYYResponse 对象中。

  • 4.5 Transport 层

该层为网络传输层,基于 Netty ,Mina 等通信框架实现。

  • 4.6 Serialize

既然涉及到网络传输,必然会把请求对象进行序列化操作。

服务暴露过程

  • 5.1 开启 Server 并监听指定端口

  • 5.2 将请求数据进行反序列化

  • 5.3 Exchanger 负责解析 Request 对象

  • 5.4 通过 Protocol 层, 根据具体协议解析 Request 对象

  • 5.5 对服务提供者的服务实现类进行代理

总结

本文结合官网的 Demo 案例, 通过画图的方式, 对 Dubbo 的框架设计图进行了简化, 目的是了解 Dubbo 框架分层的作用。

通过本文我们可以得知, 一个简单的 RPC 框架其实就是基于 动态代理 + 网络通信,

  • 动态代理 (Proxy) 就是把本地调用透明转换为远程调用

  • 远程调用就要涉及到网络通信 (Transport) – 基于 socket

  • 在 socket 基础上, 我们可以自定义我们的协议 (Protocol) ,也可以复用现有的协议,比如 http

  • 基于上面的过程, 我们可以封装 Request / Response 对象 (Exchanger)

  • 既然要网络传输, 就要想办法进行序列化/反序列化 (Serialize)

  • 当提供多个服务提供者实例时, 就应该有一个地方 (注册中心 Register) 负责管理服务提供者的元数据信息

  • 当消费者从上面的多个服务提供者 选取一个 调用服务 (Cluster) 时, 就要选取某种策略 (比如轮询, hash)

  • 最后需要一个监控中心 (Monitor) , 负责一些统计功能,比如服务调用次数

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享