dubbo学习笔记—dubbo源码简介
1.Dubbo调用关系说明
在这里主要由四部分组成:Provider
,Consumer
,Registry
,Monitor
Provider
: 暴露服务的服务提供方Protoco
l:负责提供者和消费者之间协议交互数据Service
:真实的业务服务信息 可以理解成接口和实现Container
:Dubbo
的运行环境
Consumer
: 调用远程服务的服务消费方Protocol
:负责提供者和消费者之间协议交互数据Cluster
:感知提供者端的列表信息Proxy
:可以理解成提供者的服务调用代理类
由它接管Consumer
中的接口调用逻辑
Registry
: 注册中心,用于作为服务发现和路由配置等工作,提供者和消费者都会在这里进行注册Monitor
: 用于提供者和消费者中的数据统计,比如调用频次,成功失败次数等信息。
2. Dubbo启动和执行流程说明:
-
提供者端启动,容器负责把
Service信息
加载,并通过Protocol
注册到注册中心 -
消费者端启动,通过监听提供者列表来感知提供者信息,并在提供者发生改变时,通过注册中心及时通知消费端
-
消费方发起请求,通过
Proxy
模块(代理模块) -
利用
Cluster
模块(感知提供者端的列表信息)
,来选择真实的要发送给的提供者信息 -
交由
Consumer
(消费者)中的Protocol
把信息发送给提供者
-
提供者
同样需要通过Protocol
模块来处理消费者的信息 -
最后由真正的服务提供者
Service
来进行处理
3. Dubbo整体的调用链路结构,如下图
- 淡绿色:代表了服务生产者的范围,淡蓝色:代表了服务消费者的范围,红色箭头:代表了调用的方向
- dubbo分成了三层:
- 业务逻辑层
- RPC层(远程过程调用)
- Remoting (远程数据传输)
4. Dubbo整体链路的调用流程
- 消费者通过Interface进行方法调用,统一交由消费者端的Proxy 通过ProxyFactory 来进行代理对象的创建,使用到了 jdk javassist技术
- 交给Filter这个模块,做一个统一的过滤请求(在SPI案例中涉及过)
- 接下来会进入最主要的Invoker调用逻辑
- 通过Directory 去配置中新读取信息 最终通过list方法获取所有的Invoker
- 通过Cluster模块 根据选择的具体路由规则 来选取Invoker列表
- 通过LoadBalance模块 根据负载均衡策略 选择一个具体的Invoker 来处理我们的请求
- 如果执行中出现错误 并且Consumer阶段配置了重试机制 则会重新尝试执行
- 继续经过Filter 进行执行功能的前后封装 Invoker 选择具体的执行协议
- 客户端 进行编码和序列化 然后发送数据
- 到达Consumer中的 Server 在这里进行 反编码 和 反序列化的接收数据
- 使用Exporter选择执行器
- 交给Filter 进行一个提供者端的过滤 到达 Invoker 执行器
- 通过Invoker 调用接口的具体实现 然后返回
3. Dubbo源码整体设计
- 如下图所示,图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口,位于中轴线上中间红色框是生产者和消费者双方都用到的东西
(接口/类)
- 整个体系一共分为
三层
:Business
业务层,直接面向程序员编程的,RPC
远程调用,Remoting
远程数据交互 - 其中
三大层
由下至上细化可以分成十层
:如下图所示,各层均为单向依赖,每一层也可以剥离上层被复用,可以独立被使用,其中,Service
和Config
层为API
,其它各层均为SPI
,SPI
层是可以被动态替换的。 - 图中
绿色小块
的为扩展接口,蓝色小块
为实现类,图中只显示用于关联各层的实现类。 - 图中
蓝色虚线
为初始化过程,即启动时组装链,红色实线
为方法调用过程,即运行时调时链,紫色三角箭头
为继承,可以把子类
看作父类
的同一个节点,线上的文字为调用的方法
。 Dubbo
源码整体设计与调用链路十分相似。只不过这里可以看到接口的一些具体实现以及左侧也有更为详细的层次划分,我们在后面的源码解析时也会着重介绍其中比较重要的模块实现。
4. Dubbo调用链路再说明,如下图所示
- 从start位置开始(橙色圆圈)
- 消费者(蓝色部分)是通过interface调用的,所以start指向了中轴线的interface,但这个interface也是生产者需要调用的
- 从消费者这一段的interface开始走,交由到Proxy,Proxy初始化的创建通过蓝色虚线追溯到ProxyFactory,ProxyFactory通过getProxy创建Proxy对象,而且ProxyFactory获取Proxy,是通过jdk和javassist的一些生成代理的技术
- Proxy到invoker的过程中会有一些filter过滤器,可以加可以不加
- 进入主要的invoker调用逻辑,首先invoker调用list方法,再调用到Directory的list方法,Directory会通过RegistryDirectory和RegistryProtocol,最终拿到注册中心中所有的invoker列表
- 这时候Directory调用route方法调用Router中的一个路由方法,选取一个invoker,选取一个invoker后就可以调用LoadBalance,LoadBalance根据负载均衡策略选择一个invoker进行调用
- 选完invoker,接下来通过过滤器filter,这个过滤器还要选择一个具体的协议之后,最终拿到一个invoker对象
- 消费者的invoker变成客户端,客户端要进行encode操作进行codec(编码),serialization(序列化),之后通过底层的netty/menna进行远程的数据传输
- 之后进行decode(解码)进入生产这的Server模块
- 之后用channel向上传递,组中到了Exporter,途中经过了DubboExporter,DubboHandler,其中DubboExporter选择一个Exporter(执行器)
- Exporter调用invoker方法,经过过滤器filter,过滤器filter调用invoke方法,到达顶上的invoker,invoker也是通过ProxyFactory创建的代理
- invoker调用生产者的实现类服务Implement(具体的接口实现)
5. Dubbo源码的分层结构
Business
业务逻辑层service
业务层 包括我们的业务代码 比如 接口 实现类 直接面向开发者
RPC
层 远程过程调用层config
配置层 对外提供配置 以ServiceConfig ReferenceConfig 为核心 可以直接初始化配置类 也可以解析配置文件生成proxy
服务代理层 无论是生产者 还是消费者 框架都会产生一个代理类 整个过程对上层透明 就是业务层对远程调用无感registry
注册中心层 封装服务地址的注册与发现 以服务的URL为中心cluster
路由层 (集群容错层) 提供了多个提供者的路由和负载均衡 并且它桥接注册中心 以Invoker为核心monitor
监控层 RPC调用相关的信息 如 调用次数 成功失败的情况 调用时间等 在这一层完成protocol
远程调用层 封装RPC调用 无论是服务的暴露 还是 服务的引用 都是在Protocol中作为主功能入口 负责Invoker的整个生命周期 Dubbo中所有的模型都向Invoker靠拢
Remoting
层 远程数据传输层exchange
信息交换层 封装请求和响应的模式 如把请求由同步 转换成异步transport
网络传输层 统一网络传输的接口 比如 netty 和 mina 统一为一个网络传输接口serialize
数据序列化层 负责管理整个框架中的数据传输的序列化 和反序列化