Dubbo的缓存及配置中心(三)

Dubbo的常见功能

   Dubbo序列化支持java、compactedjava、nativejava、fastjson、dubbo、fst、hessian2、kryo,其中默认hessian2。其中java、compactedjava、nativejava属于原生java的序列化。

  • dubbo序列化:阿里尚未开发成熟的高效java序列化实现,阿里不建议在生产环境使用它。
  • hessian2序列化:hessian是一种跨语言的高效二进制序列化方式。但这里实际不是原生的hessian2序列化,而是阿里修改过的,它是dubbo RPC默认启用的序列化方式。
  • json序列化:目前有两种实现,一种是采用的阿里的fastjson库,另一种是采用dubbo中自己实现的简单json库,但其实现都不是特别成熟,而且json这种文本序列化性能一般不如上面两种二进制序列化。
  • java序列化:主要是采用JDK自带的Java序列化实现,性能很不理想。

这四种主要序列化方式的性能从上到下依次递减。对于dubbo RPC这种追求高性能的远程调用方式来说,实际上只有1、2两种高效序列化方式比较般配,而第1个 dubbo 序列化由于还不成熟,所以实际只剩下2可用,所以dubbo RPC默认采用 hessian2 序列化。

但 hessian 是一个比较老的序列化实现了,而且它是跨语言的,所以不是单独针对java进行优化的。而dubbo RPC实际上完全是一种Java to Java的远程调用,其实没有必要采用跨语言的序列化方式(当然肯定也不排斥跨语言的序列化)。

 

为演示序列化支持,我们在spring-boot-server中添加

dubbo.protocol.serialization=kryo

然后导入依赖

<dependency>
            <groupId>com.esotericsoftware</groupId>
            <artifactId>kryo</artifactId>
            <version>4.0.2</version>
        </dependency>
        <dependency>
            <groupId>de.javakaffee</groupId>
            <artifactId>kryo-serializers</artifactId>
            <version>0.45</version>
        </dependency>

Dubbo调用模型   

 

 https://dubbo.apache.org/zh/docs/v2.7/user/references/xml/dubbo-reference/

 常用性能调优参数

 

 

 

 

总体架构

Dubbo的总体架构,如图所示:

 

 

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

  1. 服务接口层(Service):该层是与实际业务逻辑相关的,根据服务提供方和服务消费方的业务设计对应的接口和实现。
  2. 配置层(Config):对外配置接口,以ServiceConfig和ReferenceConfig为中心,可以直接new配置类,也可以通过spring解析配置生成配置类。
  3. 服务代理层(Proxy):服务接口透明代理,生成服务的客户端Stub和服务器端Skeleton,以ServiceProxy为中心,扩展接口为ProxyFactory。
  4. 服务注册层(Registry):封装服务地址的注册与发现,以服务URL为中心,扩展接口为RegistryFactory、Registry和RegistryService。可能没有服务注册中心,此时服务提供方直接暴露服务。
  5. 集群层(Cluster):封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster、Directory、Router和LoadBalance。将多个服务提供方组合为一个服务提供方,实现对服务消费方来透明,只需要与一个服务提供方进行交互。
  6. 监控层(Monitor):RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory、Monitor和MonitorService。
  7. 远程调用层(Protocol):封将RPC调用,以Invocation和Result为中心,扩展接口为Protocol、Invoker和Exporter。Protocol是服务域,它是Invoker暴露和引用的主功能入口,它负责Invoker的生命周期管理。Invoker是实体域,它是Dubbo的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起invoke调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。
  8. 信息交换层(Exchange):封装请求响应模式,同步转异步,以Request和Response为中心,扩展接口为Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer。
  9. 网络传输层(Transport):抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel、Transporter、Client、Server和Codec。
  10. 数据序列化层(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层,服务提供方和服务消费方之间的调用关系,如图所示:

    

节点角色说明:

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

上图中,蓝色的表示与业务有交互,绿色的表示只对Dubbo内部交互。上述图所描述的调用流程如下:

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

接着,将上面抽象的调用流程图展开,详细如图所示:

注册/注销服务
    服务的注册与注销,是对服务提供方角色而言,那么注册服务与注销服务的时序图,如图所示:

 

 

服务订阅/取消
     为了满足应用系统的需求,服务消费方的可能需要从服务注册中心订阅指定的有服务提供方发布的服务,在得到通知可以使用服务时,就可以直接调用服务。反过来,如果不需要某一个服务了,可以取消该服务。

 Dubbo缓存文件

dubbo的缓存就是为了解决在注册中心不可用时保证服务通信的高可用,为了解决这个问题,dubbo引入了缓存的概念,dubbo缓存缓存的是服务的地址,下面我们来看下dubbo的缓存怎么用

我们在消费端配置如下信息,然后启动服务,会在指定文件夹中找到缓存文件

 

 

通过上面文件我们可以发现,缓存文件缓存了我们服务的一些路径配置,当我们注册中心挂了之后,消费者可以通过文件找到要调用的接口位置信息

 

 Dubbo qos运维平台 (配置中心)

dubbo-admin是官网提供的一个控制台,可以在里面做服务的路由,我用的是dubbo admin 0.2.0 ,在操作下面动作前我们要先进入dubbo-admin-server的application.properties文件中修改zookeeper的路径

   1.拉取源代码

     git拉取网址  git clone https://github.com/apache/dubbo-admin.git

   2.前端启动

    进入dubbo-admin-ui文件夹,在地址栏输入cmd,回车打开命令窗口依次输入以下两个命令

    

#初始化vue
npm install

#运行
npm run dev

 

如果没有安装npm的朋友会失败,请自已安装npm及webpack,nodejs

npm install -g webpack

#webpack4以后需要安装这个
npm install -g webpack-cli

#检查版本
webpack -v

  

运行成功后可以访问前台页面,但目前后台没有启动,还是访问不了页面内容,下面我们启动后台

3.后台打包

进入dubbo-admin-server,打开cmd窗口,运行如下命令

官方的方法,可能会报错
#mvn clean package
mvn install -Dmaven.test.skip=true #打包,并跳过测试环节

4.启动后台

  打包完成后进入target目录,单独拿出jar包,也可以直接在目录里运行

   

java -jar dubbo-admin-server-0.2.0-SNAPSHOT.jar

 由前面动作我们已经启动了dubbo admin,下面我来展示下怎么用dubbo admin作配置中心

 

 如果我们想做配置的统一管理,我们可以在dubbo admin中做的配置管理中新建一个配置,建立一个

spring-boot-server文件然后把配置中的文件除了文件名全部剪切过来,只保留(spring.application.name=spring-boot-server)这一行

 

我们启动我们的管理工具zooInspector工具,可以在工具中看到刚刚在配置中心配置的文件信息

 

 

 

 

 

 

 

配置好配置中心后,我们要在我们的properlies中配置zookeeper配置

 

配置好后我们启动服务,会发现问题,我们在启动时会启动不了,这个错误是由于我们配置了多种协议导致的,这个跟dubbo的加载协议信息和效验协议信息的先后顺序有关,我们配置中心配置还没加载完成,dubbo就进行了协议效验,导致

了程序无法启动,为了解决这个问题我们把配置中心信息修改成下图 

dubbo.protocol.name=dubbo
dubbo.protocol.port=-1

dubbo.config-center.address=zookeeper://192.168.0.104:2181
dubbo.config-center.timeout=10000
dubbo.registry.default=true

然后取消注解中的registry和protocol

 

 

上图我们没有定制化多协议,这样dubbo在加载时会走默认协议,就不存在配置的先后顺序,这样就能解决无法启动问题

 git源码:https://github.com/ljx958720/spring-boot-dubbo1.git

 

posted @ 2021-02-10 19:42  童话述说我的结局  阅读(1237)  评论(0编辑  收藏  举报