Dubbo入门(3)-架构原理

2,292 阅读14分钟

作者:不洗碗工作室 - Marklux

出处:Dubbo入门(3)-架构原理

版权归作者所有,转载请注明出处

前言

在之前的两篇文章中,我们了解了有关分布式服务的基本概念和简单的使用。现在来了解一下dubbo是如何提供这些功能的、如何运作的,以及整个框架的层次结构。

本文参考自Dubbo架构设计详解Dubbo官方用户手册

核心功能

首先要了解Dubbo提供的三大核心功能:

  1. 通信

    提供多种对NIO框架的抽象方式,给不同服务间的互相通信及调用提供多种方式。包括同步、异步、请求与响应等模型。

  2. 服务治理

    维护服务之间的调用关系,并且提供服务容错、负载均衡、动态配置等功能。使得开发者能够实时了解服务整体的运行情况。

  3. 注册中心

    提供服务注册中心,使得服务能够动态的添加、删除并实时更新落地到消费方。

节点架构

参考dubbo官方手册提供的这个节点架构图:

解释一下各个节点所扮演的角色:

  • Provider

    暴露服务的提供方

  • Consumer

    调用远程服务的消费方

  • Container

    服务运行容器

  • Registry

    服务注册中心,用于服务发现

  • Monitor

    统计服务调用情况的监控中心

接着需要了解整体的调用关系和流程:

  1. 服务容器负责启动、加载和运行服务提供者(可以理解为:服务提供者为开发者编写的业务代码,而服务容器提供一个运行环境,使得开发者可以不用关心启动和连接的相关细节)

  2. 服务提供者在启动时,向注册中心注册自己的服务。而服务的消费者在启动时,在注册中心中订阅自己所需的服务。

  3. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。

  4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

  5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

优势特性

上述的节点架构,给dubbo带来了几个非常强大的特性,也是dubbo的优势所在:

连通性

所有的节点之间都是连通的,并且通过优化降低网络调用的消耗。

体现为:

  • 注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小
  • 监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示
  • 服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销
  • 服务消费者向注册中心获取服务提供者地址列表,并根据负载算法直接调用提供者,同时汇报调用时间到监控中心,此时间包含网络开销
  • 注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外
  • 注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者
  • 注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表
  • 注册中心和监控中心都是可选的,服务消费者可以直连服务提供者

健壮性

即便服务中的某些节点无法正常工作,系统整体不会崩溃,而是通过多种容错策略尽可能降低损失。

体现为:

  • 监控中心宕掉不影响使用,只是丢失部分采样数据
  • 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
  • 注册中心对等集群,任意一台宕掉后,将自动切换到另一台
  • 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
  • 服务提供者无状态,任意一台宕掉后,不影响使用
  • 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复

伸缩性

当服务的规模需要调整时,不必暂停服务重新部署,而是可以动态切换,体现为:

  • 注册中心为对等集群,可动态增加机器部署实例,所有客户端将自动发现新的注册中心
  • 服务提供者无状态,可动态增加机器部署实例,注册中心将推送新的服务提供者信息给消费者

升级性

当服务集群进一步增大,可能需要过渡到流动计算架构。但dubbo本身的服务结构不会为升级提供阻力。

水平分层结构

上面从节点划分的角度出发了解了dubbo的基本组件及其之间的关系,现在做一下水平分层,来看一下整个框架的所有组成,参考下图:

Dubbo框架设计一共划分了10个层,而最上面的Service层是留给实际想要使用Dubbo开发分布式服务的开发者实现业务逻辑的接口层。图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口, 位于中轴线上的为双方都用到的接口。

下面简要说明一下各层的作用(由于我还没读过源码,所以只是参考文档得出的个人理解)

  1. 服务接口层(Service)

    业务逻辑实现的地方,也是使用框架的开发者真正编写代码的地方

  2. 配置层(Config)

    配置整体运行参数的地方。

  3. 服务代理层(Proxy)

    接口调用透明化代理,将Invoker转化成用户直接调用的接口。没有这层依然可以实现RPC,但是需要用户手动组建Invoker,不能实现透明化调用。

  4. 服务注册层(Registry)

    封装服务地址的注册和发现功能,如果没有服务注册层,则需要服务提供者自己直接暴露服务调用地址。

  5. 集群层(Cluster)

    封装多个提供者的路由并提供负载均衡,桥接注册中心。实现多个服务提供方整合为一个服务提供方的映射。

  6. 监控层(Monitor)

    检测RPC的调用次数和调用情况。

  7. 远程调用层(Protocol)

    核心层,封装RPC调用。Protocol负责管理Invoker的生命周期。而Invoker是Dubbo的核心模型,代表一个 可执行体 ,所有的调用都基于Invoker,无论是本地或是远程调用,还是集群调用。

  8. 信息交换层(Exchange)

    封装各种通信模式:请求-响应、同步转异步等。

  9. 网络传输层(Transport)

    抽象mina和netty为统一接口,提供基础nio的能力。

  10. 数据序列化层(Serialize)

    提供一些基本的可复用的工具。

调用流程分析

基于下图分析在RPC层服务消费者与服务提供者之间的调度关系。

如我们之前总结的,主要分为3步:

  1. 服务提供方发布服务到服务注册中心
  2. 服务消费方从注册中心订阅服务
  3. 服务调用方调用已订阅的服务

将细节展开,参考下图:

小结

dubbo本身的结构其实并不复杂,而且分层清晰。

了解dubbo的架构,有助于理解分布式系统的设计思路,并且更容易上手。

后续也会从源码角度分析dubbo系统的实现。

前言

在之前的两篇文章中,我们了解了有关分布式服务的基本概念和简单的使用。现在来了解一下dubbo是如何提供这些功能的、如何运作的,以及整个框架的层次结构。

本文参考自Dubbo架构设计详解Dubbo官方用户手册

核心功能

首先要了解Dubbo提供的三大核心功能:

  1. 通信

    提供多种对NIO框架的抽象方式,给不同服务间的互相通信及调用提供多种方式。包括同步、异步、请求与响应等模型。

  2. 服务治理

    维护服务之间的调用关系,并且提供服务容错、负载均衡、动态配置等功能。使得开发者能够实时了解服务整体的运行情况。

  3. 注册中心

    提供服务注册中心,使得服务能够动态的添加、删除并实时更新落地到消费方。

节点架构

参考dubbo官方手册提供的这个节点架构图:

解释一下各个节点所扮演的角色:

  • Provider

    暴露服务的提供方

  • Consumer

    调用远程服务的消费方

  • Container

    服务运行容器

  • Registry

    服务注册中心,用于服务发现

  • Monitor

    统计服务调用情况的监控中心

接着需要了解整体的调用关系和流程:

  1. 服务容器负责启动、加载和运行服务提供者(可以理解为:服务提供者为开发者编写的业务代码,而服务容器提供一个运行环境,使得开发者可以不用关心启动和连接的相关细节)

  2. 服务提供者在启动时,向注册中心注册自己的服务。而服务的消费者在启动时,在注册中心中订阅自己所需的服务。

  3. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。

  4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

  5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

优势特性

上述的节点架构,给dubbo带来了几个非常强大的特性,也是dubbo的优势所在:

连通性

所有的节点之间都是连通的,并且通过优化降低网络调用的消耗。

体现为:

  • 注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小
  • 监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示
  • 服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销
  • 服务消费者向注册中心获取服务提供者地址列表,并根据负载算法直接调用提供者,同时汇报调用时间到监控中心,此时间包含网络开销
  • 注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外
  • 注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者
  • 注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表
  • 注册中心和监控中心都是可选的,服务消费者可以直连服务提供者

健壮性

即便服务中的某些节点无法正常工作,系统整体不会崩溃,而是通过多种容错策略尽可能降低损失。

体现为:

  • 监控中心宕掉不影响使用,只是丢失部分采样数据
  • 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
  • 注册中心对等集群,任意一台宕掉后,将自动切换到另一台
  • 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
  • 服务提供者无状态,任意一台宕掉后,不影响使用
  • 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复

伸缩性

当服务的规模需要调整时,不必暂停服务重新部署,而是可以动态切换,体现为:

  • 注册中心为对等集群,可动态增加机器部署实例,所有客户端将自动发现新的注册中心
  • 服务提供者无状态,可动态增加机器部署实例,注册中心将推送新的服务提供者信息给消费者

升级性

当服务集群进一步增大,可能需要过渡到流动计算架构。但dubbo本身的服务结构不会为升级提供阻力。

水平分层结构

上面从节点划分的角度出发了解了dubbo的基本组件及其之间的关系,现在做一下水平分层,来看一下整个框架的所有组成,参考下图:

Dubbo框架设计一共划分了10个层,而最上面的Service层是留给实际想要使用Dubbo开发分布式服务的开发者实现业务逻辑的接口层。图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口, 位于中轴线上的为双方都用到的接口。

下面简要说明一下各层的作用(由于我还没读过源码,所以只是参考文档得出的个人理解)

  1. 服务接口层(Service)

    业务逻辑实现的地方,也是使用框架的开发者真正编写代码的地方

  2. 配置层(Config)

    配置整体运行参数的地方。

  3. 服务代理层(Proxy)

    接口调用透明化代理,将Invoker转化成用户直接调用的接口。没有这层依然可以实现RPC,但是需要用户手动组建Invoker,不能实现透明化调用。

  4. 服务注册层(Registry)

    封装服务地址的注册和发现功能,如果没有服务注册层,则需要服务提供者自己直接暴露服务调用地址。

  5. 集群层(Cluster)

    封装多个提供者的路由并提供负载均衡,桥接注册中心。实现多个服务提供方整合为一个服务提供方的映射。

  6. 监控层(Monitor)

    检测RPC的调用次数和调用情况。

  7. 远程调用层(Protocol)

    核心层,封装RPC调用。Protocol负责管理Invoker的生命周期。而Invoker是Dubbo的核心模型,代表一个 可执行体 ,所有的调用都基于Invoker,无论是本地或是远程调用,还是集群调用。

  8. 信息交换层(Exchange)

    封装各种通信模式:请求-响应、同步转异步等。

  9. 网络传输层(Transport)

    抽象mina和netty为统一接口,提供基础nio的能力。

  10. 数据序列化层(Serialize)

    提供一些基本的可复用的工具。

调用流程分析

基于下图分析在RPC层服务消费者与服务提供者之间的调度关系。

如我们之前总结的,主要分为3步:

  1. 服务提供方发布服务到服务注册中心
  2. 服务消费方从注册中心订阅服务
  3. 服务调用方调用已订阅的服务

将细节展开,参考下图:

小结

dubbo本身的结构其实并不复杂,而且分层清晰。

了解dubbo的架构,有助于理解分布式系统的设计思路,并且更容易上手。

后续也会从源码角度分析dubbo系统的实现。