Dubbo源码解析-框架概述

990 阅读7分钟

开篇前言

Dubbo框架在我们团队的实战也差不多四五年时间了,该框架的 拆箱即用的使用特性、丰富的扩展能力和不俗的性能表现,一直深受小伙伴们的喜爱。趁着春节空闲期认真梳理下整个Dubbo框架体系内容。

1.应用架构演进过程

随着互联网的应用规模不断发展,单体应用和垂直应用架构已无法满足需求,分布式服务架构和流动式架构势在必行,需要一个合理的治理系统确保架构不断演进,一个通用架构演进架构如图所示。

        这里主要分为单体应用和垂直应用两大类型,其中垂直应用架构又演进成了分布式应用和流动计算架构。其中

  • 单体应用架构: 网站流量较小,功能模块较少,所有功能部署在一起,只需要一个应用,这样的架构需要的部署节点很少和成本也很低。此时,用于简化增删查改的数据库访问框架(ORM)是关键,如Hibernate/Mybatis/JPA框架。
  • 垂直应用架构:当访问量较大时,单一应用增加带来的性能提升效果越来越少,这里通常会将应用拆分互不相干的几个应用,以提升开发与运行效率。此时,用于提高前端页面开发效率的WEB框架(MVC)成为关键,如SpringMVC框架。
  • 分布式服务架构: 当垂直应用越来越多时,应用之间的交互会越来越多,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使应用能更快速地响应多变的市场需求。此时,用于提高业务服用以及整个分布式服务(RPC)成为架构的关键,其中如Spring Cloud/Dubbo/HSF等微服务框架为典型框架。
  •  流动计算架构:  当服务越来越多时,容量的评估、小服务资源的浪费问题逐渐显现,此时需要增加一个调度中心基于访问压力实时管理集群容量,提高集群利用。此时,用于提高机器利用率的资源调度和治理中心是关键。

2.Dubbo架构

       Dubbo框架主要由注册中心Registry、消费者Consumer、生产者Provider、监控Monitor等四大部分组成。

  • Provider在启动时会向注册中心把自己的元数据注册上去(比如服务提供者所在得到实例IP和端口,服务接口的相关配置等)
  • Consumer在启动时会从注册中心会全量拉取服务提供方的元数据到本地缓存中,并订阅相关元数据变更事件,注册中心发生数据变更事会推送给订阅的Consumer。
  • 在获取服务元数据后,Consumer可以发起RPC调用,在RPC调用前后会异步向监控中心上报统计信息。

3.Dubbo分层

一个设计精良的系统或框架肯定是有非常合理的分层设计的,系统/框架分层从逻辑上将子系统划分成许多集合,而层间关系的形成要遵循一定的规则。通过分层,可以限制子系统间的依赖关系,使系统以更松散的方式耦合,从而更易于维护。

子系统的分组标准包含以下几条规则可见度。各子系统只能与同一层及其下一层的子系统存在依赖关系。通过软件设计分层,以下是Dubbo框架的分层结构,其中Service和Config可以认为API层,提供给API,只需要配置和完成业务代码即可;后面的所有层级合在一起,可以认为是SPI层,主要提供给扩展者使用,即用户可以基于Dubbo框架做定制的二次开发,扩展其功能。

在该层次图中,可以看到每一层级都会有比较核心的接口来支撑整个层次的逻辑,后面篇章内容会围绕这些核心接口开展。

  • Service: 业务层,主要是开发者实现的业务代码;
  • Config: 配置层,主要围绕ServiceConfig(暴露的服务配置) 和 ReferenConfig(引用的服务配置) 两个实现类展开,初始化配置信息;
  • Proxy: 服务代理层,无论生产者还是消费者,都会生成一个代理类,整个过程对上层是透明的;
  • Registry: 注册层,负责服务注册与发现,当有新的服务加入或旧服务下线时,注册中心都会感知并通知给所有订阅方;
  • Cluster: 集群容错层,主要负责远程调用失败时的容错策略(如失败重试、快速失败),选z择具体调用节点时的负载均衡策略(如随机、一致性hash等); 特殊调用路径的路由策略 (如某个消费者只会调用某个IP的生产者);
  • Monitor: 监控层,主要负责监控调用次数和调用时间等;
  • Protocol: 远程调用层,封装RPC调用的具体过程,Protocol是的Invoker暴露(发布一个服务让别人可以调用)和引用(引用一个远程服务到本地)的主功能入口,它负责管理Invoker的整个生命周期;
  • Exchange: 信息交换层,建立请求-响应模型,如把同步请求转化为异步请求;
  • Transport: 网络传输层次,把网络传输封装为统一的接口;
  • Serialize: 序列化层, 如果数据要通过网络进行发送,则需要先进行序列化,变成二进制。序列化层负责整个框架网络传输时的序列化/反序列化工作。

4.Dubbo总体调用过程 

        从下图中可以看到,一个调用过程从消费者的一个Proxy过程开始的, Proxy持有一个Invoker对象,然后触发Invoke调用操作,在invoke调用过程中,需要使用Cluster,它负责集群的容错,如调用失败的重试。Cluster在调用之前会通过Directory获取所有可以调用的远程服务Invoker列表(一个接口可能会有多个节点提供服务)。通过LoadBalance方法做负载均衡,最终选出一个可以调用的Invoker。这个Invoker在调用之前会经过一个过滤器链,这个过滤器链通常是处理上下文、限流、计数等。

        接着,会使用Client做数据传输,如我们常见的Netty Client等。传输之前肯定会做一些私有协议的构造,此时就会使用Codec接口,构造完成后,就对数据包做序列化,然后传输到服务提供者段,服务提供者端接收到数据包,也会使用Codec处理协议头以及一些半包、黏包等,处理完成后再对完整的数据报文做反序列化处理。

        随后,这个Request会分配到线程池(Threadpool)中进行处理。Server会处理这些Request,根据请求查找对应的Exporter(它内部持有了Invoker),Invoker是被用装饰器模式一层一层套了非常多的Filterd,因此在调用最终的实现类之前,又会经过一个服务提供者的过滤器链路。最后,得到了具体接口的真正实现并调用,再把结果原路返回。

5.Dubbo功能特性

    Dubbo过合理的分层、高性能、高扩展的设计方法与技术实现后,具备了以下几个功能特性:

  • 高性能的RPC调用: 提供高性能的基于代理的远程调用能力,服务以接口为粒度,为开发者屏蔽了远程底层调用细节;
  • 服务自注册与发现: 支持多种注册中心服务,服务实例上下线实时感知;
  • 运行期间流量监控与调度: 内置条件、文件等路由策略实现,通过配置不同的路由规则,可实现灰度发布、同机房优先等功能;
  • 智能负载均衡: 内置多种负载均衡策略,
  • 高度可扩展能力: 遵循微内核+插件的设计思想,所有核心能力都被设计成扩展点,可以方便内置和实现第三方实现;
  • 可视化的服务治理与运维: 提供丰富服务治理、运维工具.

6.总结

       本篇是Dubbo整个框架源码解析的开篇,通过介绍Dubbo的架构分层、核心组件、总体的调用流程,让有兴趣的小伙伴们可以先对Dubbo框架有个大概的了解与认识。

参考文献

blog.csdn.net/e5max/artic…