代码架构

总体设计

/dev-guide/images/dubbo-framework.jpg

图示

  • 图中左侧淡蓝色背景为服务消费者使用的接口,右侧淡绿色背景为服务提供者使用的接口,中间轴线上的接口为双方共同使用的接口。
  • 图中从下往上分为十层,每层都是单向依赖,右侧黑色箭头代表层与层之间的依赖关系,每层都可以剥离上层进行复用。其中 Service 和 Config 层是 API,其他层是 SPI。
  • 图中绿色小块是扩展接口,蓝色小块是实现类,图中只展示了与每层关联的实现类。
  • 图中蓝色虚线是初始化过程,即启动时的组装链,红色实线是方法调用过程,即运行时调用链,紫色三角形箭头是继承关系,可以将子类看作父类的同一个节点,线上面的文字是调用的方法。

各层描述

  • Config 配置层:外部配置接口,以 ServiceConfigReferenceConfig 为中心,可以直 接初始化配置类,也可以通过 spring 解析配置生成配置类
  • Proxy 服务代理层:服务接口透明代理,生成服务客户端 Stub 和服务器 Skeleton,以 ServiceProxy 为中心,扩展接口为 ProxyFactory
  • Registry 注册中心层:封装服务地址的注册与发现,以服务 URL 为中心,扩展接口为 RegistryFactoryRegistryRegistryService
  • Cluster 路由层:封装多个提供者的路由与负载均衡,并桥接注册中心,以 Invoker 为中心,扩展接口为 ClusterDirectoryRouterLoadBalance
  • Monitor 监控层:RPC 调用次数和调用时间监控,以 Statistics 为中心,扩展接口为 MonitorFactoryMonitorMonitorService
  • Protocol 远程调用层:封装 RPC 调用,以 InvocationResult 为中心,扩展接口为 ProtocolInvokerExporter
  • Exchange 信息交换层:封装请求响应模式,同步到异步,以 RequestResponse 为中心,扩展接口为 ExchangerExchangeChannelExchangeClientExchangeServer
  • Transport 网络传输层:抽象 mina 和 netty 为统一接口,以 Message 为中心,扩展接口为 ChannelTransporterClientServerCodec
  • Serialize 数据序列化层:一些可复用的工具,扩展接口为 SerializationObjectInputObjectOutputThreadPool

关系描述

  • 在 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 传输,交换层在传输层之上封装了请求-响应语义。
  • 注册中心和监控中心实际上并不算作一层,而是一个独立的节点,只是为了全局概述,才将其绘制在一起。

模块子包

/dev-guide/images/dubbo-modules.jpg

模块描述

  • 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 模块中,以便更好地复用。

依赖关系

/dev-guide/images/dubbo-relation.jpg

图示

  • 图中的小方块 Protocol、Cluster、Proxy、Service、Container、Registry、Monitor 代表层级或模块,蓝色表示它们与业务交互,绿色表示它们只与 Dubbo 内部交互。
  • 图中的背景方块 Consumer、Provider、Registry、Monitor 代表部署逻辑拓扑节点。
  • 图中的蓝色虚线表示初始化时的调用,红色虚线表示运行时的异步调用,红色实线表示运行时的同步调用。
  • 图中只包含 RPC 层,不包含 Remoting 层。Remoting 被隐式地包含在整个 Protocol 中。

调用链

扩展通用设计图中的红色调用链,如下所示

/dev-guide/images/dubbo-extension.jpg

暴露服务时序

扩展通用设计图右侧服务提供者暴露服务的蓝色初始化链,时序图如下所示

/dev-guide/images/dubbo-export.jpg

引用服务时序

扩展通用设计图左侧服务消费者引用服务的绿色初始化链,时序图如下所示

/dev-guide/images/dubbo-refer.jpg

领域模型

在 Dubbo 的核心领域模型中

  • Protocol 是服务领域,是 Invoker 暴露和引用的主要功能入口,负责 Invoker 的生命周期管理。
  • Invoker 是一个实体领域,它是 Dubbo 的核心模型,其他模型都与它紧密相关,或者转换为它,它代表一个可执行体,可以向它发起 invoke 调用,它可能是一个本地实现,也可能是一个远程实现,甚至可能是一个集群实现。
  • Invocation 是一个会话领域,它保存调用过程中的变量,例如方法名、参数等。

基本设计原则

  • 采用微内核 + 插件模式,微内核只负责组装插件,Dubbo 自身的功能也是通过扩展点实现的,即 Dubbo 的所有功能点都可以被用户自定义的扩展替换。
  • URL 用作配置信息的统一格式,所有扩展点都通过传递 URL 来携带配置信息。

上次修改时间:2023 年 1 月 2 日:增强英文文档 (#1798) (95a9f4f6c1c)