二.项目结构
1. 概述
本文主要分享 Dubbo 的项目结构。
希望通过本文能让胖友对 Dubbo 的整体项目有个简单的了解。
另外,笔者会相对大量引用 《Dubbo 用户指南》 和 《Dubbo 开发指南》 ,写的真的挺好的。
ps:限于排版,部分地方引用会存在未标明的情况。
在拉取 Dubbo 项目后,我们会发现拆分了好多 Maven 项目。是不是内心一紧,产生了恐惧感?不要方,我们就是继续怼。
2. 代码统计
这里先分享一个小技巧。笔者在开始源码学习时,会首先了解项目的代码量。
第一种方式,使用 IDEA Statistic 插件,统计整体代码量。
我们可以粗略的看到,总的代码量在 98210 行。这其中还包括单元测试,示例等等代码。
所以,不慌。
第二种方式,使用 Shell 脚本命令逐个 Maven 模块统计 。
一般情况下,笔者使用 find . -name "*.java"|xargs cat|grep -v -e ^$ -e ^\s*\/\/.*$|wc -l
。这个命令只过滤了部分注释,所以相比 IDEA Statistic 会偏多。
当然,考虑到准确性,胖友需要手动 cd
到每个 Maven 项目的 src/main/java
目录下,以达到排除单元测试的代码量。
3. 项目一览
如果胖友看过 《Dubbo 框架设计》 ,就会发现有下面这张图。
通过这图,我们可以很清晰的知道几个 Maven 模块的依赖关系。
3.1 dubbo-common
dubbo-common
公共逻辑模块:提供工具类和通用模型。
工具类比较好理解,通用模型是什么?举个例子,com.alibaba.dubbo.common.URL
:
FROM 《Dubbo 开发指南 —— 公共契约》
- 所有扩展点参数都包含 URL 参数,URL 作为上下文信息贯穿整个扩展点设计体系。
- URL 采用标准格式:
protocol://username:password@host:port/path?key=value&key=value
。
3.2 dubbo-remoting
dubbo-remoting
远程通信模块:提供通用的客户端和服务端的通讯功能。
dubbo-remoting-zookeeper
,相当于 Zookeeper Client ,和 Zookeeper Server 通信。dubbo-remoting-api
, 定义了 Dubbo Client 和 Dubbo Server 的接口。- 实现
dubbo-remoting-api``dubbo-remoting-grizzly
,基于 Grizzly 实现。dubbo-remoting-http
,基于 Jetty 或 Tomcat 实现。dubbo-remoting-mina
,基于 Mina 实现。dubbo-remoting-netty
,基于 Netty 3 实现。dubbo-remoting-netty4
,基于 Netty 4 实现。dubbo-remoting-p2p
,P2P 服务器。注册中心dubbo-registry-multicast
项目的使用该项目。
从最小化的角度来看,我们只需要看:
dubbo-remoting-api
+dubbo-remoting-netty4
dubbo-remoting-zookeeper
3.3 dubbo-rpc
dubbo-rpc
远程调用模块:抽象各种协议,以及动态代理,只包含一对一的调用,不关心集群的管理。
- 集群相关的管理,由
dubbo-cluster
提供特性。
在回过头看上面的图,我们会发现,dubbo-rpc
是整个 Dubbo 的中心。
dubbo-rpc-api
,抽象各种协议以及动态代理,实现了一对一的调用。- 其他模块,实现
dubbo-rpc-api
,提供对应的协议实现。在 《用户指南 —— 协议参考手册》 中,可以看到每种协议的介绍。 - 另外,
dubbo-rpc-default
对应dubbo://
协议。 - 拓展参见 《Dubbo 开发指南 —— 协议扩展》 文档。
进一步的拆解,见 《精尽 Dubbo 源码分析 —— 核心流程一览》 文章。
3.4 dubbo-cluster
dubbo-cluster
集群模块:将多个服务提供方伪装为一个提供方,包括:负载均衡, 集群容错,路由,分组聚合等。集群的地址列表可以是静态配置的,也可以是由注册中心下发。
- 注册中心下发,由
dubbo-registry
提供特性。
- 容错
com.alibaba.dubbo.rpc.cluster.Cluster
接口 +com.alibaba.dubbo.rpc.cluster.support
包。- Cluster 将 Directory 中的多个 Invoker 伪装成一个 Invoker,对上层透明,伪装过程包含了容错逻辑,调用失败后,重试另一个。
- 拓展参见 《Dubbo 用户指南 —— 集群容错》 和 《Dubbo 开发指南 —— 集群扩展》 文档。
- 目录
com.alibaba.dubbo.rpc.cluster.Directory
接口 +com.alibaba.dubbo.rpc.cluster.directory
包。- Directory 代表了多个 Invoker ,可以把它看成 List ,但与 List 不同的是,它的值可能是动态变化的,比如注册中心推送变更。
- 路由
com.alibaba.dubbo.rpc.cluster.Router
接口 +com.alibaba.dubbo.rpc.cluster.router
包。- 负责从多个
Invoker
中按路由规则选出子集,比如读写分离,应用隔离等。 - 拓展参见 《Dubbo 用户指南 —— 路由规则》 和 《Dubbo 开发指南 —— 路由拓展》 文档。
- 配置
com.alibaba.dubbo.rpc.cluster.Configurator
接口 +com.alibaba.dubbo.rpc.cluster.configurator
包。- 拓展参见 《Dubbo 用户指南 —— 配置规则》 文档。
- 负载均衡
com.alibaba.dubbo.rpc.cluster.LoadBalance
接口 +com.alibaba.dubbo.rpc.cluster.loadbalance
包。- LoadBalance 负责从多个 Invoker 中选出具体的一个用于本次调用,选的过程包含了负载均衡算法,调用失败后,需要重选。
- 拓展参见 《Dubbo 用户指南 —— 负载均衡》 和 《Dubbo 开发指南 —— 负载均衡拓展》 文档。
- 合并结果
com.alibaba.dubbo.rpc.cluster.Merger
接口 +com.alibaba.dubbo.rpc.cluster.merger
包。- 合并返回结果,用于分组聚合。
- 拓展参见 《Dubbo 用户指南 —— 分组聚合》 和 《Dubbo 开发指南 —— 合并结果扩展》 文档。
整体流程如下:
3.5 dubbo-registry
dubbo-registry
注册中心模块:基于注册中心下发地址的集群方式,以及对各种注册中心的抽象。
dubbo-registry-api
,抽象注册中心的注册与发现接口。- 其他模块,实现
dubbo-registry-api
,提供对应的注册中心实现。在 《用户指南 —— 注册中心参考手册》 中,可以看到每种注册中心的介绍。 - 另外,
dubbo-registry-default
对应 Simple 注册中心。 - 拓展参见 《Dubbo 开发指南 —— 注册中心扩展》 文档。
3.6 dubbo-monitor
dubbo-monitor
监控模块:统计服务调用次数,调用时间的,调用链跟踪的服务。
- 拓展参见 《Dubbo 开发指南 —— 监控中心扩展》 。
目前社区里,有对 Dubbo 监控中心进行重构的项目,例如 :
3.7 dubbo-config
dubbo-config
配置模块:是 Dubbo 对外的 API,用户通过 Config 使用Dubbo,隐藏 Dubbo 所有细节。
dubbo-config
配置模块:是 Dubbo 对外的 API,用户通过 Config 使用Dubbo,隐藏 Dubbo 所有细节。
3.8 dubbo-container
dubbo-container
容器模块:是一个 Standlone 的容器,以简单的 Main 加载 Spring 启动,因为服务通常不需要 Tomcat/JBoss 等 Web 容器的特性,没必要用 Web 容器去加载服务。
dubbo-container-api
:定义了com.alibaba.dubbo.container.Container
接口,并提供 加载所有容器启动的 Main 类。- 实现
dubbo-container-api``dubbo-container-spring
,提供了com.alibaba.dubbo.container.spring.SpringContainer
。dubbo-container-log4j
,提供了com.alibaba.dubbo.container.log4j.Log4jContainer
。dubbo-container-logback
,提供了com.alibaba.dubbo.container.logback.LogbackContainer
。 - 拓展参考 《Dubbo 用户指南 —— 服务容器》 和 《Dubbo 开发指南 —— 容器扩展》 文档。
3.9 dubbo-filter
dubbo-filter
过滤器模块:提供了内置的过滤器。
dubbo-filter-cache
,缓存过滤器。拓展参考 《Dubbo 用户指南 —— 结果缓存》 和 《Dubbo 开发指南 —— 缓存拓展》 文档。dubbo-filter-validation
,参数验证过滤器。拓展参考 《Dubbo 用户指南 —— 参数验证》 和 《Dubbo 开发指南 —— 验证扩展》 文档。
3.10 dubbo-plugin
dubbo-plugin
插件模块:提供了内置的插件。
dubbo-qos
,提供在线运维命令。拓展参考 《Dubbo 用户指南 —— 新版本 telnet 命令使用说明》 和 《Dubbo 开发指南 —— Telnet 命令扩展》 文档。
3.11 hessian-lite
hessian-lite
:Dubbo 对 Hessian 2 的 序列化 部分的精简、改进、BugFix 。
提交历史如下:
3.12 dubbo-demo
dubbo-demo
快速启动示例。
参见 《Dubbo 用户指南 —— 快速启动》 文档。
3.13 dubbo-test
dubbo-test
测试模块。
dubbo-test-benchmark
,性能测试。参考 《Dubbo 用户指南 —— 性能测试报告》 文档。dubbo-test-compatibility
,兼容性测试。dubbo-test-spring3
,测试对 Spring 3 的兼容性。dubbo-test-example
,使用示例。
3.14 Maven POM
3.14.1 dubbo-dependencies-bom
dubbo-dependencies-bom/pom.xml
,Maven BOM(Bill Of Materials) ,统一定义了 Dubbo 依赖的三方库的版本号:
dubbo-parent
会引入该 BOM :
更多 Maven BOM 的知识,可以看下 《Maven 与Spring BOM(Bill Of Materials)简化Spring版本控制》 文档:
通俗解说:
为了防止用 Maven 管理 Spring 项目时,不同的项目依赖了不同版本的 Spring ,可以使用 Maven BOM 来解决者一问题。
3.14.2 dubbo-bom
dubbo-bom/pom.xml
,Maven BOM(Bill Of Materials) ,统一定义了 Dubbo 的版本号:
dubbo-demo
和 dubbo-test
会引入该 BOM 。以 dubbo-demo
举例子:
3.14.3 dubbo-parent
dubbo/pom.xml
,Dubbo Parent Pom 。
Dubbo 的 Maven 模块,都会引入该 pom 文件。以 dubbo-cluster
举例子:
我们整理下上面的 pom 文件:
3.14.4 dubbo-all
dubbo/all/pom.xml
,Dubbo All Pom ,定义了 Dubbo 的打包脚本。
我们在使用 Dubbo 库时,引入该 pom 文件。