Dubbo原理和功能介绍

4,957 阅读9分钟

原文:segmentfault.com/a/119000001…

原理

基础概念

Dubbo就是SOA服务治理方案的核心框架。用于分布式调用,其重点在于分布式的治理。

Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合),比如表现层和业务层就需要解耦合。

从面向服务的角度来看,Dubbo采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务,所以基于这一点可以抽象出服务提供方(Provider)和服务消费方(Consumer)两个角色。

除了以上两个角色,它还有注册中心和监控中心。它可以通过注册中心对服务进行注册和订阅;可以通过监控中心对服务进行监控,这样的话,就可以知道哪些服务使用率高、哪些服务使用率低。对使用率高的服务增加机器,对使用率低的服务减少机器,达到合理分配资源的目的。

Dubbo核心功能

1、Remoting:远程通讯,提供对多种NIO框架抽象封装,包括“同步转异步”和“请求-响应”模式的信息交换方式。
2、Cluster:服务框架,提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
3、Registry:服务注册,基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。

Dubbo组件角色

clipboard.png

Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor: 统计服务的调用次调和调用时间的监控中心。
Container: 服务运行容器,常见的容器有Spring容器。

调用关系说明:

  1. 服务容器负责启动,加载,运行服务提供者。
  2. 服务提供者在启动时,向注册中心注册自己提供的服务。
  3. 服务消费者在启动时,向注册中心订阅自己所需的服务。
  4. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  5. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  6. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心Monitor。

Dubbo总体架构

上面介绍给出的都是抽象层面的组件关系,可以说是纵向的以服务模型的组件分析,其实Dubbo最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。所以,我们横向以分层的方式来看下Dubbo的架构,如图所示:

clipboard.png
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。
从上图可以看出,Dubbo对于服务提供方和服务消费方,从框架的10层中分别提供了各自需要关心和扩展的接口,构建整个服务生态系统(服务提供方和服务消费方本身就是一个以服务为中心的)。

根据官方提供的,对于上述各层之间关系的描述,如下所示:
1、在RPC中,Protocol是核心层,也就是只要有Protocol + Invoker + Exporter就可以完成非透明的RPC调用,然后在Invoker的主过程上Filter拦截点。

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

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

4、Proxy层封装了所有接口的透明化代理,而在其它层都以Invoker为中心,只有到了暴露给用户使用时,才用Proxy将Invoker转成接口,或将接口实现转成Invoker,也就是去掉Proxy层RPC是可以Run的,只是不那么透明,不那么看起来像调本地服务一样调远程服务。
5、而Remoting实现是Dubbo协议的实现,如果你选择RMI协议,整个Remoting都不会用上,Remoting内部再划为Transport传输层和Exchange信息交换层,Transport层只负责单向消息传输,是对Mina、Netty、Grizzly的抽象,它也可以扩展UDP传输,而Exchange层是在传输层之上封装了Request-Response语义。

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

服务调用流程

clipboard.png

连接方式

1、直连:

不通过注册中心,直接由消费者访问提供者。

2、集群:

提供者把服务注册到注册中心,然后消费者询问注册中心,请求对应的服务需要请求哪个提供者,注册中心返回结果,消费者根据结果向提供者请求服务。

3、超时和重连机制:

(1)dubbo超时,不会返回结果,直接报异常
(2)配置超时重试次数、超时时间:
    ```
        <!-- 服务调用超时设置为5秒,超时不重试-->
        <dubbo:service interface="com.provider.service.DemoService" ref="demoService"  retries="0" timeout="5000"/>
    ```
(3)dubbo在调用服务不成功时,默认会重试2次。
    Dubbo的路由机制,会把超时的请求路由到其他机器上,而不是本机尝试,所以 dubbo的重试机器也能一定程度的保证服务的质量。但是如果不合理的配置重试次数,当失败时会进行重试多次,这样在某个时间点出现性能问题,调用方再连续重复调用,系统请求变为正常值的retries倍,系统压力会大增,容易引起服务雪崩,需要根据业务情况规划好如何进行异常处理,何时进行重试。

group及version

1、group:用于对服务进行隔离,这里可以实现灰度功能的作用。
2、version:当一个接口的实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用

问题(走过的坑)

1、Dubbo调用接口,该接口抛出的运行时异常,在调用函数里面无法捕获的
2、一个经典问题: Forbid consumer 127.0.0.1 access service com.mall.api.service.MallService from registry localhost:2181 use dubbo version 2.9.2-SNAPSHOT, Please check registry access list (whitelist/blacklist).

这个错误一般表面上说禁止消费服务,实际上开发人员并没有做任何限制。其实,这个问题一般由两种情况引起的
(1)第一种情况:没有provider提供对应的服务
(2)第二种情况:消费者消费的服务的“版本号 version”和生产者提供的服务的“版本号 version”不一致,或者没有显式说明版本号。

3、当dubbo超时,返回的结果会为null
4、dubbo如果报异常了,dubbo不会返回错误码,因此需要在对外提供的接口处利用参数传递错误码、错误信息
5、在dubbo的provider和consumer的配置文件中,如果都配置了timeout的超时时间,dubbo默认以consumer中配置的时间为准。