个人学习分布式专题(二)分布式服务治理之Dubbo框架

目录

 Dubbo框架

  1.1 Dubbo是什么

  1.2 Dubbo企业级应用示例(略)

  1.3 Dubbo实现原理及架构剖析

  1.4 Dubbo+Spring集成


 

Dubbo框架

  1.1 Dubbo是什么:Dubbo是一个分布式服务框架,致力于提高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的。告别web service模式中的WSdl,以服务者与消费者的方式在dubbo上注册。

dubbo可满足的基本需求:

  • 服务多,压力大:一个服务注册中心,动态的注册和发现服务,使服务的位置透明。并通过在消费方获取服务提供方地址列表,实现软负载均衡和 Failover,降低对 F5 硬件负载均衡器的依赖,也能减少部分成本。
  • 服务依赖复杂:需要自动画出应用间的依赖关系图,以帮助架构师理清理关系。
  • 服务调用量变大,服务容量不够:第一步,要将服务现在每天的调用量,响应时间,都统计出来,作为容量规划的参考指标。其次,要可以动态调整权重,在线上,将某台机器的权重一直加大,并在加大的过程中记录响应时间的变化,直到响应时间到达阀值,记录此时的访问量,再以此访问量乘以机器数反推总容量。

 

  1.3 Dubbo实现原理及架构剖析:(转自 http://dubbo.apache.org/books/dubbo-dev-book/)

    Dubbo的最大特点是按照分层的方式来架构,使用这种方式可以使各层之间解耦和(或大程度的松耦合)。从服务模型的角度来看,dubbo采用的是一种非常简单的模型,要么使提供方提供服务,要么使消费方消费服务,所以基于这一点可以抽象出服务提供方Provider和服务消费方consumer两个角色。

    Dubbo总体架构,如图所示:

               dubbo总体架构

 

    Dubbo框架设计一共划分了10个层,而最上面的Service层使留给实际想要使用Dubbo开发分布式服务的开发者实现业务的接口,左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口, 位于中轴线上的为双方都用到的接口。
              下面,结合Dubbo官方文档,我们分别理解一下框架分层架构中,各个层次的设计要点:

    • 服务接口层(Service):该层是与实际业务逻辑相关的,根据服务提供方和服务消费方的业务设计对应的接口和实现。

    • 配置层(Config):对外配置接口,以ServiceConfig和ReferenceConfig为中心,可以直接new配置类,也可以通过spring解析配置生成配置类。

    • 服务代理层(Proxy):服务接口透明代理,生成服务的客户端Stub和服务器端Skeleton,以ServiceProxy为中心,扩展接口为ProxyFactory。

    • 服务注册层(Registry):封装服务地址的注册与发现,以服务URL为中心,扩展接口为RegistryFactory、Registry和RegistryService。可能没有服务注册中心,此时服务提供方直接暴露服务。

    • 集群层(Cluster):封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster、Directory、Router和LoadBalance。将多个服务提供方组合为一个服务提供方,实现对服务消费方来透明,只需要与一个服务提供方进行交互。

    • 监控层(Monitor):RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory、Monitor和MonitorService。

    • 远程调用层(Protocol):封将RPC调用,以Invocation和Result为中心,扩展接口为Protocol、Invoker和Exporter。Protocol是服务域,它是Invoker暴露和引用的主功能入口,它负责Invoker的生命周期管理。Invoker是实体域,它是Dubbo的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起invoke调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。

    • 信息交换层(Exchange):封装请求响应模式,同步转异步,以Request和Response为中心,扩展接口为Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer。

    • 网络传输层(Transport):抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel、Transporter、Client、Server和Codec。

    • 数据序列化层(Serialize):可复用的一些工具,扩展接口为Serialization、 ObjectInput、ObjectOutput和ThreadPool。

    

关系说明

    • 在 RPC 中,Protocol 是核心层,也就是只要有 Protocol + Invoker + Exporter 就可以完成非透明的 RPC 调用,然后在 Invoker 的主过程上 Filter 拦截点。

    • 图中的 Consumer 和 Provider 是抽象概念,只是想让看图者更直观的了解哪些类分属于客户端与服务器端,不用 Client 和 Server 的原因是 Dubbo 在很多场景下都使用 Provider, Consumer, Registry, Monitor 划分逻辑拓普节点,保持统一概念。

    • 而 Cluster 是外围概念,所以 Cluster 的目的是将多个 Invoker 伪装成一个 Invoker,这样其它人只要关注 Protocol 层 Invoker 即可,加上 Cluster 或者去掉 Cluster 对其它层都不会造成影响,因为只有一个提供者时,是不需要 Cluster 的。

    • Proxy 层封装了所有接口的透明化代理,而在其它层都以 Invoker 为中心,只有到了暴露给用户使用时,才用 Proxy 将 Invoker 转成接口,或将接口实现转成 Invoker,也就是去掉 Proxy 层 RPC 是可以 Run 的,只是不那么透明,不那么看起来像调本地服务一样调远程服务。

    • 而 Remoting 实现是 Dubbo 协议的实现,如果你选择 RMI 协议,整个 Remoting 都不会用上,Remoting 内部再划为 Transport 传输层和 Exchange 信息交换层,Transport 层只负责单向消息传输,是对 Mina, Netty, Grizzly 的抽象,它也可以扩展 UDP 传输,而 Exchange 层是在传输层之上封装了 Request-Response 语义。

    • Registry 和 Monitor 实际上不算一层,而是一个独立的节点,只是为了全局概览,用层的方式画在一起。


     从上面的架构图中,我们可以了解到,Dubbo作为一个分布式服务框架,主要具有如下几个核心的要点:

    服务定义

    服务是围绕服务提供方和服务消费方的,服务提供方实现服务,而服务消费方调用服务。

服务注册

对于服务提供方,它需要发布服务,而且由于应用系统的复杂性,服务的数量、类型也不断膨胀;对于服务消费方,它最关心如何获取到它所需要的服务,而面对复杂的应用系统,需要管理大量的服务调用。而且,对于服务提供方和服务消费方来说,他们还有可能兼具这两种角色,即既需要提供服务,有需要消费服务。
通过将服务统一管理起来,可以有效地优化内部应用对服务发布/使用的流程和管理。服务注册中心可以通过特定协议来完成服务对外的统一。Dubbo提供的注册中心有如下几种类型可供选择:

      • Multicast注册中心
      • Zookeeper注册中心
      • Redis注册中心
      • Simple注册中心

      远程通信与信息交换

   远程通信需要指定通信双方所约定的协议,在保证通信双方理解协议语义的基础上,还要保证高效、稳定的消息传输。Dubbo继承了当前主流的网络通信框架,主要包括如下几个:

      • Mina
      • Netty
      • Grizzly

          服务调用

         下面从Dubbo官网直接拿来,看一下基于RPC层,服务提供方和服务消费方之间的调用关系,如图所示:

                   DUBBO服务调用

      

调用链

展开总设计图的红色调用链,如下:

调用链

 

暴露服务时序

展开总设计图左边服务提供方暴露服务的蓝色初始化链,时序图如下:

      暴露服务时序

      

引用服务时序

展开总设计图右边服务消费方引用服务的蓝色初始化链,时序图如下:

引用服务时序

领域模型

在 Dubbo 的核心领域模型中:

      • Protocol 是服务域,它是 Invoker 暴露和引用的主功能入口,它负责 Invoker 的生命周期管理。
      • Invoker 是实体域,它是 Dubbo 的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起 invoke 调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。
      • Invocation 是会话域,它持有调用过程中的变量,比如方法名,参数等。

 

猜你喜欢

转载自www.cnblogs.com/hangzhi/p/9077135.html