作者:不洗碗工作室 - Marklux
版权归作者所有,转载请注明出处
前言
在之前的两篇文章中,我们了解了有关分布式服务的基本概念和简单的使用。现在来了解一下dubbo是如何提供这些功能的、如何运作的,以及整个框架的层次结构。
本文参考自Dubbo架构设计详解及Dubbo官方用户手册
核心功能
首先要了解Dubbo提供的三大核心功能:
-
通信
提供多种对NIO框架的抽象方式,给不同服务间的互相通信及调用提供多种方式。包括同步、异步、请求与响应等模型。
-
服务治理
维护服务之间的调用关系,并且提供服务容错、负载均衡、动态配置等功能。使得开发者能够实时了解服务整体的运行情况。
-
注册中心
提供服务注册中心,使得服务能够动态的添加、删除并实时更新落地到消费方。
节点架构
参考dubbo官方手册提供的这个节点架构图:
解释一下各个节点所扮演的角色:
-
Provider
暴露服务的提供方
-
Consumer
调用远程服务的消费方
-
Container
服务运行容器
-
Registry
服务注册中心,用于服务发现
-
Monitor
统计服务调用情况的监控中心
接着需要了解整体的调用关系和流程:
-
服务容器负责启动、加载和运行服务提供者(可以理解为:服务提供者为开发者编写的业务代码,而服务容器提供一个运行环境,使得开发者可以不用关心启动和连接的相关细节)
-
服务提供者在启动时,向注册中心注册自己的服务。而服务的消费者在启动时,在注册中心中订阅自己所需的服务。
-
注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
-
服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
-
服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
优势特性
上述的节点架构,给dubbo带来了几个非常强大的特性,也是dubbo的优势所在:
连通性
所有的节点之间都是连通的,并且通过优化降低网络调用的消耗。
体现为:
- 注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小
- 监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示
- 服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销
- 服务消费者向注册中心获取服务提供者地址列表,并根据负载算法直接调用提供者,同时汇报调用时间到监控中心,此时间包含网络开销
- 注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外
- 注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者
- 注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表
- 注册中心和监控中心都是可选的,服务消费者可以直连服务提供者
健壮性
即便服务中的某些节点无法正常工作,系统整体不会崩溃,而是通过多种容错策略尽可能降低损失。
体现为:
- 监控中心宕掉不影响使用,只是丢失部分采样数据
- 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
- 注册中心对等集群,任意一台宕掉后,将自动切换到另一台
- 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
- 服务提供者无状态,任意一台宕掉后,不影响使用
- 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复
伸缩性
当服务的规模需要调整时,不必暂停服务重新部署,而是可以动态切换,体现为:
- 注册中心为对等集群,可动态增加机器部署实例,所有客户端将自动发现新的注册中心
- 服务提供者无状态,可动态增加机器部署实例,注册中心将推送新的服务提供者信息给消费者
升级性
当服务集群进一步增大,可能需要过渡到流动计算架构。但dubbo本身的服务结构不会为升级提供阻力。
水平分层结构
上面从节点划分的角度出发了解了dubbo的基本组件及其之间的关系,现在做一下水平分层,来看一下整个框架的所有组成,参考下图:
Dubbo框架设计一共划分了10个层,而最上面的Service层是留给实际想要使用Dubbo开发分布式服务的开发者实现业务逻辑的接口层。图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口, 位于中轴线上的为双方都用到的接口。
下面简要说明一下各层的作用(由于我还没读过源码,所以只是参考文档得出的个人理解)
-
服务接口层(Service)
业务逻辑实现的地方,也是使用框架的开发者真正编写代码的地方
-
配置层(Config)
配置整体运行参数的地方。
-
服务代理层(Proxy)
接口调用透明化代理,将Invoker转化成用户直接调用的接口。没有这层依然可以实现RPC,但是需要用户手动组建Invoker,不能实现透明化调用。
-
服务注册层(Registry)
封装服务地址的注册和发现功能,如果没有服务注册层,则需要服务提供者自己直接暴露服务调用地址。
-
集群层(Cluster)
封装多个提供者的路由并提供负载均衡,桥接注册中心。实现多个服务提供方整合为一个服务提供方的映射。
-
监控层(Monitor)
检测RPC的调用次数和调用情况。
-
远程调用层(Protocol)
核心层,封装RPC调用。Protocol负责管理Invoker的生命周期。而Invoker是Dubbo的核心模型,代表一个 可执行体 ,所有的调用都基于Invoker,无论是本地或是远程调用,还是集群调用。
-
信息交换层(Exchange)
封装各种通信模式:请求-响应、同步转异步等。
-
网络传输层(Transport)
抽象mina和netty为统一接口,提供基础nio的能力。
-
数据序列化层(Serialize)
提供一些基本的可复用的工具。
调用流程分析
基于下图分析在RPC层服务消费者与服务提供者之间的调度关系。
如我们之前总结的,主要分为3步:
- 服务提供方发布服务到服务注册中心
- 服务消费方从注册中心订阅服务
- 服务调用方调用已订阅的服务
将细节展开,参考下图:
小结
dubbo本身的结构其实并不复杂,而且分层清晰。
了解dubbo的架构,有助于理解分布式系统的设计思路,并且更容易上手。
后续也会从源码角度分析dubbo系统的实现。
前言
在之前的两篇文章中,我们了解了有关分布式服务的基本概念和简单的使用。现在来了解一下dubbo是如何提供这些功能的、如何运作的,以及整个框架的层次结构。
本文参考自Dubbo架构设计详解及Dubbo官方用户手册
核心功能
首先要了解Dubbo提供的三大核心功能:
-
通信
提供多种对NIO框架的抽象方式,给不同服务间的互相通信及调用提供多种方式。包括同步、异步、请求与响应等模型。
-
服务治理
维护服务之间的调用关系,并且提供服务容错、负载均衡、动态配置等功能。使得开发者能够实时了解服务整体的运行情况。
-
注册中心
提供服务注册中心,使得服务能够动态的添加、删除并实时更新落地到消费方。
节点架构
参考dubbo官方手册提供的这个节点架构图:
解释一下各个节点所扮演的角色:
-
Provider
暴露服务的提供方
-
Consumer
调用远程服务的消费方
-
Container
服务运行容器
-
Registry
服务注册中心,用于服务发现
-
Monitor
统计服务调用情况的监控中心
接着需要了解整体的调用关系和流程:
-
服务容器负责启动、加载和运行服务提供者(可以理解为:服务提供者为开发者编写的业务代码,而服务容器提供一个运行环境,使得开发者可以不用关心启动和连接的相关细节)
-
服务提供者在启动时,向注册中心注册自己的服务。而服务的消费者在启动时,在注册中心中订阅自己所需的服务。
-
注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
-
服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
-
服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
优势特性
上述的节点架构,给dubbo带来了几个非常强大的特性,也是dubbo的优势所在:
连通性
所有的节点之间都是连通的,并且通过优化降低网络调用的消耗。
体现为:
- 注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小
- 监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示
- 服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销
- 服务消费者向注册中心获取服务提供者地址列表,并根据负载算法直接调用提供者,同时汇报调用时间到监控中心,此时间包含网络开销
- 注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外
- 注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者
- 注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表
- 注册中心和监控中心都是可选的,服务消费者可以直连服务提供者
健壮性
即便服务中的某些节点无法正常工作,系统整体不会崩溃,而是通过多种容错策略尽可能降低损失。
体现为:
- 监控中心宕掉不影响使用,只是丢失部分采样数据
- 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
- 注册中心对等集群,任意一台宕掉后,将自动切换到另一台
- 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
- 服务提供者无状态,任意一台宕掉后,不影响使用
- 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复
伸缩性
当服务的规模需要调整时,不必暂停服务重新部署,而是可以动态切换,体现为:
- 注册中心为对等集群,可动态增加机器部署实例,所有客户端将自动发现新的注册中心
- 服务提供者无状态,可动态增加机器部署实例,注册中心将推送新的服务提供者信息给消费者
升级性
当服务集群进一步增大,可能需要过渡到流动计算架构。但dubbo本身的服务结构不会为升级提供阻力。
水平分层结构
上面从节点划分的角度出发了解了dubbo的基本组件及其之间的关系,现在做一下水平分层,来看一下整个框架的所有组成,参考下图:
Dubbo框架设计一共划分了10个层,而最上面的Service层是留给实际想要使用Dubbo开发分布式服务的开发者实现业务逻辑的接口层。图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口, 位于中轴线上的为双方都用到的接口。
下面简要说明一下各层的作用(由于我还没读过源码,所以只是参考文档得出的个人理解)
-
服务接口层(Service)
业务逻辑实现的地方,也是使用框架的开发者真正编写代码的地方
-
配置层(Config)
配置整体运行参数的地方。
-
服务代理层(Proxy)
接口调用透明化代理,将Invoker转化成用户直接调用的接口。没有这层依然可以实现RPC,但是需要用户手动组建Invoker,不能实现透明化调用。
-
服务注册层(Registry)
封装服务地址的注册和发现功能,如果没有服务注册层,则需要服务提供者自己直接暴露服务调用地址。
-
集群层(Cluster)
封装多个提供者的路由并提供负载均衡,桥接注册中心。实现多个服务提供方整合为一个服务提供方的映射。
-
监控层(Monitor)
检测RPC的调用次数和调用情况。
-
远程调用层(Protocol)
核心层,封装RPC调用。Protocol负责管理Invoker的生命周期。而Invoker是Dubbo的核心模型,代表一个 可执行体 ,所有的调用都基于Invoker,无论是本地或是远程调用,还是集群调用。
-
信息交换层(Exchange)
封装各种通信模式:请求-响应、同步转异步等。
-
网络传输层(Transport)
抽象mina和netty为统一接口,提供基础nio的能力。
-
数据序列化层(Serialize)
提供一些基本的可复用的工具。
调用流程分析
基于下图分析在RPC层服务消费者与服务提供者之间的调度关系。
如我们之前总结的,主要分为3步:
- 服务提供方发布服务到服务注册中心
- 服务消费方从注册中心订阅服务
- 服务调用方调用已订阅的服务
将细节展开,参考下图:
小结
dubbo本身的结构其实并不复杂,而且分层清晰。
了解dubbo的架构,有助于理解分布式系统的设计思路,并且更容易上手。
后续也会从源码角度分析dubbo系统的实现。