代码架构
总体设计
图示
- 图中左侧淡蓝色背景为服务消费者使用的接口,右侧淡绿色背景为服务提供者使用的接口,中间轴线上的接口为双方共同使用的接口。
- 图中从下往上分为十层,每层都是单向依赖,右侧黑色箭头代表层与层之间的依赖关系,每层都可以剥离上层进行复用。其中 Service 和 Config 层是 API,其他层是 SPI。
- 图中绿色小块是扩展接口,蓝色小块是实现类,图中只展示了与每层关联的实现类。
- 图中蓝色虚线是初始化过程,即启动时的组装链,红色实线是方法调用过程,即运行时调用链,紫色三角形箭头是继承关系,可以将子类看作父类的同一个节点,线上面的文字是调用的方法。
各层描述
- Config 配置层:外部配置接口,以
ServiceConfig
、ReferenceConfig
为中心,可以直 接初始化配置类,也可以通过 spring 解析配置生成配置类 - Proxy 服务代理层:服务接口透明代理,生成服务客户端 Stub 和服务器 Skeleton,以
ServiceProxy
为中心,扩展接口为ProxyFactory
- Registry 注册中心层:封装服务地址的注册与发现,以服务 URL 为中心,扩展接口为
RegistryFactory
、Registry
、RegistryService
- Cluster 路由层:封装多个提供者的路由与负载均衡,并桥接注册中心,以
Invoker
为中心,扩展接口为Cluster
、Directory
、Router
、LoadBalance
- Monitor 监控层:RPC 调用次数和调用时间监控,以
Statistics
为中心,扩展接口为MonitorFactory
、Monitor
、MonitorService
- Protocol 远程调用层:封装 RPC 调用,以
Invocation
、Result
为中心,扩展接口为Protocol
、Invoker
、Exporter
- Exchange 信息交换层:封装请求响应模式,同步到异步,以
Request
、Response
为中心,扩展接口为Exchanger
、ExchangeChannel
、ExchangeClient
、ExchangeServer
- Transport 网络传输层:抽象 mina 和 netty 为统一接口,以
Message
为中心,扩展接口为Channel
、Transporter
、Client
、Server
、Codec
- 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 不会影响其他层,因为只有一个 Provider,不需要 Cluster。
- Proxy 层封装了所有接口的透明代理,Invoker 是其他层中的中心。只有当它暴露给用户时,Proxy 用于将 Invoker 转换为接口,或将接口实现转换为 Invoker,即移除 Proxy 层 RPC 可以运行,但它不那么透明,看起来不像调用本地服务一样调用远程服务。
- 远程调用实现是 Dubbo 协议的实现。如果您选择 RMI 协议,则不会使用整个远程调用。远程调用分为传输层和信息交换层。传输层只负责单向消息传输,Netty、Grizzly 的抽象,也可以扩展 UDP 传输,交换层在传输层之上封装了请求-响应语义。
- 注册中心和监控中心实际上并不算作一层,而是一个独立的节点,只是为了全局概述,才将其绘制在一起。
模块子包
模块描述
- dubbo-common 公共逻辑模块:包含 Util 类和通用模型。
- dubbo-remoting 远程通信模块:相当于 Dubbo 协议的实现,如果 RPC 使用 RMI 协议,则不需要使用此包。
- dubbo-rpc 远程调用模块:抽象各种协议和动态代理,只包含一对一调用,不关心集群管理。
- dubbo-cluster 集群模块:将多个服务提供者伪装成一个提供者,包括:负载均衡、容错、路由等。集群的地址列表可以静态配置,也可以由注册中心发送配置。
- dubbo-registry 注册中心模块:基于注册中心发布的集群方式,以及各种注册中心的抽象。
- dubbo-monitor 监控模块:统计服务调用次数、调用时间以及调用链跟踪服务。
- dubbo-config 配置模块:Dubbo 的外部 API,用户通过 Config 使用 Dubbo,隐藏了 Dubbo 的所有细节。
- dubbo-container 容器模块:是一个 Standlone 容器,加载一个简单的 Main 来启动 Spring,因为服务通常不需要 Tomcat/JBoss 等 Web 容器的功能,所以不需要使用 Web 容器来加载服务。
总体而言,子包是按照层次结构进行的。与分层不同的是
- 容器是一个服务容器,用于部署和运行服务,并没有绘制在层级中。
- 协议层和代理层都放置在 rpc 模块中。这两个层是 rpc 的核心。当不需要集群时,即只有一个提供者,就可以只使用这两个层来完成 rpc 调用。
- 传输层和交换层都放置在 remoting 模块中,是 rpc 调用的通信基础。
- 序列化层放置在 common 模块中,以便更好地复用。
依赖关系
图示
- 图中的小方块 Protocol、Cluster、Proxy、Service、Container、Registry、Monitor 代表层级或模块,蓝色表示它们与业务交互,绿色表示它们只与 Dubbo 内部交互。
- 图中的背景方块 Consumer、Provider、Registry、Monitor 代表部署逻辑拓扑节点。
- 图中的蓝色虚线表示初始化时的调用,红色虚线表示运行时的异步调用,红色实线表示运行时的同步调用。
- 图中只包含 RPC 层,不包含 Remoting 层。Remoting 被隐式地包含在整个 Protocol 中。
调用链
扩展通用设计图中的红色调用链,如下所示
暴露服务时序
扩展通用设计图右侧服务提供者暴露服务的蓝色初始化链,时序图如下所示
引用服务时序
扩展通用设计图左侧服务消费者引用服务的绿色初始化链,时序图如下所示
领域模型
在 Dubbo 的核心领域模型中
- Protocol 是服务领域,是 Invoker 暴露和引用的主要功能入口,负责 Invoker 的生命周期管理。
- Invoker 是一个实体领域,它是 Dubbo 的核心模型,其他模型都与它紧密相关,或者转换为它,它代表一个可执行体,可以向它发起 invoke 调用,它可能是一个本地实现,也可能是一个远程实现,甚至可能是一个集群实现。
- Invocation 是一个会话领域,它保存调用过程中的变量,例如方法名、参数等。
基本设计原则
- 采用微内核 + 插件模式,微内核只负责组装插件,Dubbo 自身的功能也是通过扩展点实现的,即 Dubbo 的所有功能点都可以被用户自定义的扩展替换。
- URL 用作配置信息的统一格式,所有扩展点都通过传递 URL 来携带配置信息。
上次修改时间:2023 年 1 月 2 日:增强英文文档 (#1798) (95a9f4f6c1c)