分布式RPC系统框架Dubbo-20Dubbo系统架构分析

1-Dubbo的系统架构分析

        阿里系的RPC框架;

  • hsf:淘宝正在使用的RPC框架;
  • sofa:蚂蚁经正在使用的RPC框架;
  • dubbo:阿里B2B开发的RPC框架;

1.1 Dubbo的两大设计原则

       Dubbo框架在设计时遵循两大设计原则:

  • Dubbo使用“微内核+组件”的设计模式;内核只负责组装插件(扩展点),Dubbo的功能都是由插件实现的,也就是Dubbo的所有功能点都可以被用户自定义扩展类所替代,只需要增加某功能接口的实现类即可实现业务功能;

  • 采用URL作为配置信息的统一格式,所有扩展点都通过传递URL携带配置信息;

1.1.1微内核+组件设计模式

       此种设计模式的扩展性非常强,内核只负责组装插件,插件即扩展点,本质是接口的实现类,dubbo的具体功能都是由插件实现,此处的接口为SPI接口;

2 Dubbo的三大领域模型

        为了对Dubbo整体架构叙述的方便,Dubbo抽象除了三大领域模型;

(1)Protocol服务域:是Invoker暴露和引用的主要功能入口,它负载Invoker的生命周期管理;

(2)Invoker实体域:是Dubbo的核心模型,其它模型都向它靠拢,或转换为它,它代表一个可执行体,可以向它发起invoke调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能是一个集群实现;

  • Invoker类似于proxy代理对象,proxy在dubbo中代理的是consumer,而Invoker代理的是provider;

(3)Invocation会话域:代表数据传递,它持有调用过程中的变量,比如方法名,参数等;

3 Dubbo的四大组件

分布式RPC系统框架Dubbo-20Dubbo系统架构分析

  • Provider:服务提供者[Container容器]。

  • Consumer:服务消费者。

  • Registry:服务注册与发现的中心,提供目录服务,亦称为服务注册中心。

  • Monitor:统计服务的调用次数、调用时间等信息的日志服务,并可以对服务设置权限、降级处理等,称为服务管控中心。

        Container容器(spring)启动,创建Provider,创建完成后register注册到Registry(Zookeeper)注册中心(初始化注册一次),同时Consumer根据业务请求向Registry注册中心subscribe订阅服务(Consumer的订阅与Provider的注册没有先后顺序),Consumer订阅过程中如果注册中心没有此服务(即还未注册或未完成的情况)其不会阻塞,其会继续订阅其他服务,当所需服务注册后异步notify通知Consumer订阅,实际的订阅工作是Consumer从Registry下载一个服务注册表,然后通过负载均衡的方式同步Invoke调用注册表中的Provider集群(一般都是以集群的方式提供服务),此处调用默认采用同步方式(可以调整为异步方式不阻塞),当Consumer调用Provider,而Provider又调用某些耗时的IO操作默认同步阻塞(可以调整为异步方式不阻塞),此时Consumer就会阻塞;Provider与Consumer会定时向Monitor汇报调用情况,Monitor将这些汇报情况count统计汇总,呈现数据反馈,根据数据情况可以通过<服务治理中心>对系统进行资源调配。

4 Dubbo十层架构

        十层架构是Dubbo源码的表现逻辑,Dubbo的内核并未在此图中;

分布式RPC系统框架Dubbo-20Dubbo系统架构分析

4.1 三个规划层

        十层结构可以规划为三个大层:

  • Business业务层

    Service业务层是用户自己实现的代码;

  • RPC(远程过程调用)

    包含Config、Proxy、Registry、Cluster、Monitor、Protocol共6层,这6层完成的是远程调用过程

  • Remoting(远程调用)

    真正实现远程调用;

4.2 各层说明

  • config 配置层

    对外配置接口,以 ServiceConfig, ReferenceConfig 为中心,可以直接初始化配置类,也可以通过 spring 解析配置生成配置类;

    将dubbo配置文件中的配置(标签),解析为对象,consumer对象为ReferenceConfig,provider对象为ServiceConfig,再将对象读取到内存,即.xml文件中的配置读取到内存中;

  • proxy 服务代理层

    服务接口透明代理,生成服务的客户端 Stub 和服务器端 Skeleton, 以 ServiceProxy 为中心,扩展接口为 ProxyFactory

    Invoker为provider的代理对象,Proxy为consumer的代理对象;

  • registry 注册中心层

    封装服务地址的注册与发现,以服务 URL 为中心,扩展接口为 RegistryFactory, Registry, RegistryService

    consumer与provider注册到注册中心,并且中注册中心下载注册表,consumer与provider都要下载,在生产环境下生产者与消费者之间并非明确划分界限;

  • cluster 路由层

    封装多个提供者的路由及负载均衡,并桥接注册中心,以 Invoker 为中心,扩展接口为 Cluster, Directory, Router, LoadBalance

    将注册中心中相同服务业务接口的provider包装合并成一个cluster(集群),将cluster合并成一个Invoker,对外表现为一个Invoker,Invoker通过list获取Direcroty提供者列表,然后通过route过滤不需要的provider,在同select调用Loadbalance负载均衡调用一个provider;dubbo服务治理基本上发生在cluster层;

  • monitor 监控层

    RPC 调用次数和调用时间监控,以 Statistics 为中心,扩展接口为 MonitorFactory, Monitor, MonitorService

  • protocol 远程调用层

    封装 RPC 调用,以 Invocation, Result 为中心,扩展接口为 Protocol, Invoker, Exporter

    dubbo协议层;

  • exchange 信息交换层

    封装请求响应模式,同步转异步,以 Request, Response 为中心,扩展接口为 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer

    RPC层为同步处理层,consumer与provider由exchange层开始转换为异步,默认底层是通过netty实现的转换;

  • transport 网络传输层

    抽象 mina 和 netty 为统一接口,以 Message 为中心,扩展接口为 Channel, Transporter, Client, Server, Codec

    转换完成后在此层进行传输;

  • serialize 数据序列化层

    可复用的一些工具,扩展接口为 Serialization, ObjectInput, ObjectOutput, ThreadPool

    此为netty的底层,进行各种序列化与底层传输;

5 Dubbo框架结构

5.1 将dubbo源码导入

        Dubbo2.7.3源码解析;

5.2 模块说明

  • 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 容器去加载服务。

整体上按照分层结构进行分包,与分层的不同点在于:

  • container 为服务容器,用于部署运行服务,没有在层中画出。

  • protocol 层和 proxy 层都放在 rpc 模块中,这两层是 rpc 的核心,在不需要集群也就是只有一个提供者时,可以只使用这两层完成 rpc 调用。

  • transport 层和 exchange 层都放在 remoting 模块中,为 rpc 调用的通讯基础。

  • serialize 层放在 common 模块中,以便更大程度复用。