12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用

文章目录

  • 1、分布式理论
  • 2、什么是RPC
  • 3、Dubbo
    • 3.1、什么是Dubbo?
    • 3.2、dubbo基本概念
    • 3.3、Dubbo环境搭建
      • 3.3.1、Window下安装Zookeeper
      • 3.3.2、window下安装dubbo-admin
        • 3.3.2.1、旧版dubbo-admin
        • 3.3.2.2、新版dubbo-admin
  • 4、SpringBoot + Dubbo + Zookeeper 整合
    • 4.1、spring整合dubbo
    • 4.2、springboot整合dubbo
  • 5、dubbo配置相关介绍
  • 6、dubbo高可用
    • 6.1、zookeeper宕机与dubbo直连
    • 6.2、集群下dubbo负载均衡的配置
  • 7、dubbo原理
    • 7.1、RPC原理
    • 7.2、netty通信原理

1、分布式理论

1.1、 什么是分布式系统?

分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像是单个相关系统。分布式系统(distributed system)是建立在网络之上的软件系统。随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。

首先需要明确的是,只有当单个节点的处理能力无法满足日益增长的计算、存储任务的时候,且硬件的提升(加内存、加磁盘、使用更好的CPU)高昂到得不偿失的时候,应用程序也不能进一步优化的时候,我们才需要考虑分布式系统。因为,分布式系统要解决的问题本身就是和单机系统一样的,而由于分布式系统多节点、通过网络通信的拓扑结构,会引入很多单机系统没有的问题,为了解决这些问题又会引入更多的机制、协议,带来更多的问题。。。

1.2、 Dubbo文档

随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,急需一个治理系统确保架构有条不紊的演进。

背景:

12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第1张图片

1.3、单一应用架构

当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键

12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第2张图片

适用于小型网站,小型管理系统,将所有功能都部署到一个功能里,简单易用。

缺点:

  • 性能扩展比较难

  • 协同开发问题

  • 不利于升级维护

1.4、垂直应用架构

当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,提升效率的方法之一是将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的Web框架(MVC)是关键

12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第3张图片
通过切分业务来实现各个模块独立部署,降低了维护和部署的难度,团队各司其职更易管理,性能扩展也更方便,更有针对性。

缺点:公用模块无法重复利用,开发性的浪费

1.5、分布式服务架构

当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服务框架(RPC)是关键

12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第4张图片

1.6、流动计算架构

当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键

12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第5张图片

2、什么是RPC

RPC【Remote Procedure Call】是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范。 它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即程序员无论是调用本地的还是远程的函数,本质上编写的调用代码基本相同。

也就是说 两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。 为什么要用RPC呢?就是无法在一个进程内,甚至一个计算机内通过本地调用的方式完成的需求,比如不同的系统间的通讯,甚至不同的组织间的通讯,由于计算能力需要横向扩展,需要在多台机器组成的集群上部署应用。RPC就是要像调用本地的函数一样去调远程函数;

推荐阅读文章:https://www.jianshu.com/p/2accc2840a1b

12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第6张图片

步骤解析:

12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第7张图片

RPC两个核心模块:通讯,序列化。

3、Dubbo

3.1、什么是Dubbo?

Apache Dubbo |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:

  • 面向接口的远程方法调用
  • 智能容错和负载均衡
  • 以及服务自动注册和发现
  • dubbo官网

学习方法:

  • Dubbo 的特性
    • 面向接口代理的高性能RPC调用:提供高性能的基于代理的远程服务调用能力,服务以接口为粒度,为开发者屏蔽远程调用的底层细节
    • 智能负载均衡:内置多种负载均衡策略,智能感知下游节点健康状况,显著减少调用延迟,提高系统吞吐量
    • 服务自动注册与发现:支持多种注册中心服务,服务实例上下线实时感知
    • 高度可扩展能力
    • 运行期流量调度
    • 可视化的服务治理与运维

3.2、dubbo基本概念

12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第8张图片

1、服务发现:服务发现的一个核心组件是注册中心,Provider注册地址到注册中心,Consumer消费者从注册中心读取和订阅Provider地址列表。因此,要启用服务发现,需要为Dubbo增加注册中心配置
2、RPC通信协议:协议是RPC的核心,它规范了数据在网络中的传输内容和格式。除必须的请求、响应数据外,通常还会包含额外控制数据,如单次请求的序列化方式、超时时间、压缩方式和鉴权信息等。

dubbo框架容器(Container):启动后开始初始化
服务提供者(Provider):暴露服务的服务提供方,服务提供者在启动时,向注册中心注册自己提供的服务

服务消费者(Consumer):调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务,服务消费者从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

注册中心(Registry):注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者

监控中心(Monitor):服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心

调用关系说明

  • 服务容器负责启动,加载,运行服务提供者

  • 服务提供者在启动时,向注册中心 注册 自己提供的服务

  • 服务消费者在启动时,向注册中心 订阅 自己所需的服务

  • 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者

  • 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用

  • 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心

3.3、Dubbo环境搭建

官网推荐注册中心使用Zookeeper注册中心,那么什么是 zookeeper呢?可以查看官方文档

3.3.1、Window下安装Zookeeper

  • 下载后直接解压Zookeeper

  • 运行bin目录下的zkServer.cmd ,初次运行会报错,因为没有zoo.cfg配置文件,可能遇到问题:闪退 !

  • 解决方案:

    • 编辑zkServer.cmd文件末尾添加pause 。这样运行出错就不会退出,会提示错误信息,方便找到原因

      在这里插入图片描述
      所报错误:

      在这里插入图片描述
      修改zoo.cfg配置文件,将conf文件夹下面的zoo_sample.cfg复制一份改名为zoo.cfg即可

      在这里插入图片描述

  • 注意几个重要位置:

    • dataDir=./data 临时数据存储的目录(可写相对路径)

    • clientPort=2181 zookeeper的端口号

    • 修改完成后再次启动zookeeper
      在这里插入图片描述

  • 启动成功后使用zkCli.cmd测试

    • ls /:列出zookeeper根下保存的所有节点
      在这里插入图片描述

    • create -e /jinglei 123:创建一个jinglei节点,值为123
      在这里插入图片描述

    • get /jinglei:获取/jinglei节点的值
      在这里插入图片描述

    • 我们再来查看一下节点

      在这里插入图片描述

3.3.2、window下安装dubbo-admin

3.3.2.1、旧版dubbo-admin

dubbo-admin : 是一个监控管理后台,可以查看我们注册了哪些服务,哪些服务被消费了dubbo本省并不是一个服务软件。它其实就是一个jar包,能够帮你的java程序连接到zookeeper,并利用zookeeper消费、提供服务,但是为了为了让用户更好的管理监控众多的dubbo服务,官方提供可一个可视化的监控程序dubbo-admin,不过这个监控即使不装也不影响使用

安装步骤

  • 下载dubbo-admin,下载地址:地址

  • 解压进入目录,修改dubbo-admin\src\main\resources \application.properties配置文件, 指定zookeeper地址
    在这里插入图片描述

  • 在项目目录(dubbo-admin)下打包dubbo-admin

    mvn clean package -Dmaven.test.skip=true
    
  • 第一次打包的过程有点慢,需要耐心等待!直到成功
    在这里插入图片描述

  • 运行dubbo-admin\target目录下的dubbo-admin-0.0.1-SNAPSHOT.jar,命令:java -jar dubbo-admin-0.0.1-SNAPSHOT.jar

  • 注意:zookeeper的服务一定要打开!

  • 执行完毕后,我们去访问一下 http://localhost:7001/ , 这时候我们需要输入登录账户和密码,我们都是默认的root-root

  • 登录成功后,查看界面
    12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第9张图片

  • 至此,安装完成!

3.3.2.2、新版dubbo-admin

安装步骤

  • 下载dubbo-admin,下载地址:地址
  • 修改服务的端口号,默认是8080,我将端口号改为7001dubbo-admin-develop\dubbo-admin-server\src\main\resources\application.properties12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第10张图片
  • 在项目目录(dubbo-admin-develop)下打包执行命令
    mvn clean package -Dmaven.test.skip=true
    
  • 这里会报一个错在这里插入图片描述
  • 进入到dubbo-admin-ui目录下执行npm install(注意这里需要node环境)12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第11张图片
  • 在项目目录(dubbo-admin-develop)下再次执行打包命令12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第12张图片
  • 执行dubbo-admin-develop\dubbo-admin-distribution\target下的dubbo-admin-0.4.0.jar,命令:java -jar dubbo-admin-0.4.0.jar
    12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第13张图片
  • 访问http://localhost:7001/,默认用户名和密码都是root12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第14张图片
  • 至此,安装完成!

4、SpringBoot + Dubbo + Zookeeper 整合

4.1、spring整合dubbo

需求:

  • 某个电商系统,订单服务需要调用用户服务获取某个用户的所有地址
  • 我们现在需要创建两个服务模块进行测试
模块 功能
订单服务web模块 创建订单等
用户服务service模块 查询用户地址等

测试预期结果:订单服务web模块在A服务器,用户服务模块在B服务器,A可以远程调用B的功能


创建spring-common模块:公共接口层(model,service,exception…),定义公共接口,也可以导入公共依赖 UserAddress.java:用户地址实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserAddress implements Serializable {
    private Integer id;
    private String userAddress; //用户地址
    private String userId;  //用户id
    private String consignee; //收货人
    private String phoneNum; //电话号码啊
    private String isDefault; //是否为默认地址 Y——是,N——否
}

ProviderService订单接口

/**
* 用户服务
*/
public interface ProviderService {

   /**
    * 根据用户id返回所有的收获地址
    *
    * @param userId
    * @return
    */
   public List<UserAddress> getUserAddressList(String userId);
}

ConsumerService消费接口

public interface ConsumerService {

    /**
     * 初始化订单
     *
     * @param userId
     */
    public void initProvider(String userId);
}

pom.xml文件

    <dependencies>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>dubboartifactId>
            <version>2.6.2version>
        dependency>
        
        <dependency>
            <groupId>org.apache.curatorgroupId>
            <artifactId>curator-frameworkartifactId>
            <version>2.12.0version>
            
            <exclusions>
                <exclusion>
                    <groupId>org.apache.zookeepergroupId>
                    <artifactId>zookeeperartifactId>
                exclusion>
            exclusions>
        dependency>

        
        <dependency>
            <groupId>org.apache.zookeepergroupId>
            <artifactId>zookeeperartifactId>
            <version>3.4.7version>
        dependency>
    dependencies>

创建spring-provider模块:用户业务,作为服务提供者,pom.xml文件中:引入通用模块,可以使用定义的接口

    <dependencies>
        <dependency>
            <groupId>com.springcloudgroupId>
            <artifactId>spring-commonartifactId>
            <version>1.0-SNAPSHOTversion>
        dependency>
    dependencies>

ProviderServiceImpl:ProviderService的实现类, 供远程调用

public class ProviderServiceImpl implements ProviderService {

    @Override
    public List<UserAddress> getUserAddressList(String userId) {
        UserAddress userAddress1 = new UserAddress(1, "北京市", "123", "喜羊羊", "18222933678", "Y");
        UserAddress userAddress2 = new UserAddress(2, "天津市", "123", "懒羊羊", "12222933338", "N");
        return Arrays.asList(userAddress1, userAddress2);
    }
}

provider.xml:dubbo配置信息


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:bean="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    
    <dubbo:application name="provider-service">dubbo:application>
    
    <dubbo:registry address="zookeeper://127.0.0.1:2181">dubbo:registry>
    
    <dubbo:protocol name="dubbo" port="20880">dubbo:protocol>
    
    <bean id="providerServiceImpl" class="com.spring.study.Service.impl.ProviderServiceImpl">bean>
    
    <dubbo:service interface="com.spring.study.service.ProviderService" ref="providerServiceImpl">dubbo:service>

beans>

ProviderApplication启动类

public class ProviderApplication {
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("provider.xml");
        applicationContext.start();

        System.in.read();
    }
}
  • 启动zookerper,启动dubbo-admin,这里用于可视化
    12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第15张图片
  • 查看应用
    12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第16张图片

创建spring-consumer模块:用户业务,作为服务消费者,pom.xml文件中:引入通用模块,可以使用定义的接口

    <dependencies>
        <dependency>
            <groupId>com.springcloudgroupId>
            <artifactId>spring-commonartifactId>
            <version>1.0-SNAPSHOTversion>
        dependency>
    dependencies>

ConsumerServiceImpl :ConsumerService的实现类, 供远程调用

/**
 * 1.将服务提供者注册到注册中心(暴露服务)
 * 1.1.导入dubbo依赖
 * 1.2.配置服务提供者
 * 2.让服务消费者去注册中心订阅服务提供者的服务地址
 */
@Service
public class ConsumerServiceImpl implements ConsumerService {

    /**
     * @param userId
     */
    @Autowired
    ProviderService providerService;

    @Override
    public void initProvider(String userId) {
        //1.查询用户的收获地址
        System.out.println("用户id:" + userId);
        List<UserAddress> addressList = providerService.getUserAddressList(userId);
        for (UserAddress userAddress : addressList) {
            System.out.println(userAddress.getUserAddress());
        }
    }
}

consumer.xml:dubbo配置信息


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    
    <context:component-scan base-package="com.spring.study.service.impl">context:component-scan>
    
    <dubbo:application name="consumer-service">dubbo:application>
    
    <dubbo:registry address="zookeeper://127.0.0.1:2181">dubbo:registry>
    
    <dubbo:reference interface="com.spring.study.service.ProviderService" id="providerService">dubbo:reference>

beans>

ConsumerApplication启动类

public class ConsumerApplication {
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("consumer.xml");
        ConsumerService consumerService = context.getBean(ConsumerService.class);
        consumerService.initProvider("123");
        System.out.println("调用完成");
        System.in.read();
    }
}

结果

12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第17张图片
12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第18张图片

4.2、springboot整合dubbo

创建springboot-common模块:公共接口层(model,service,exception…),定义公共接口,也可以导入公共依赖 UserAddress.java:用户地址实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserAddress implements Serializable {
    private Integer id;
    private String userAddress; //用户地址
    private String userId;  //用户id
    private String consignee; //收货人
    private String phoneNum; //电话号码啊
    private String isDefault; //是否为默认地址 Y——是,N——否
}

ProviderService订单接口

/**
* 用户服务
*/
public interface ProviderService {

   /**
    * 根据用户id返回所有的收获地址
    *
    * @param userId
    * @return
    */
   public List<UserAddress> getUserAddressList(String userId);
}

ConsumerService消费接口

public interface ConsumerService {

    /**
     * 初始化订单
     *
     * @param userId
     */
    public List<UserAddress> initProvider(String userId);
}

创建springboot-provider模块:用户业务,作为服务提供者,pom.xml文件中:引入通用模块,可以使用定义的接口

    <dependencies>
        <dependency>
            <groupId>com.springcloudgroupId>
            <artifactId>springboot-commonartifactId>
            <version>1.0-SNAPSHOTversion>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>com.alibaba.bootgroupId>
            <artifactId>dubbo-spring-boot-starterartifactId>
            <version>0.2.0version>
        dependency>
    dependencies>

ProviderServiceImpl:ProviderService的实现类, 供远程调用

注意需要添加@Service注解暴露服务

@Service //暴露服务,dubbo的注解
public class ProviderServiceImpl implements ProviderService {

    @Override
    public List<UserAddress> getUserAddressList(String userId) {
        UserAddress userAddress1 = new UserAddress(1, "北京市", "123", "喜羊羊", "18222933678", "Y");
        UserAddress userAddress2 = new UserAddress(2, "天津市", "123", "懒羊羊", "12222933338", "N");
        return Arrays.asList(userAddress1, userAddress2);
    }
}

application.yml:dubbo配置信息

dubbo:
  #应用名称
  application:
    name: provider-service
  #注册中心地址
  registry:
    address: 127.0.0.1:2181
    protocol: zookeeper
  #指定通信协议
  protocol:
    name: dubbo
    port: 20880

ProviderApplication启动类

@EnableDubbo //开启基于注解的dubbo功能
@SpringBootApplication
public class ProviderApplication {
    /**
     * 操作步骤
     * 1.导入依赖——dubbo相关依赖(dubbo-starter)
     * 2.配置yml文件(dubbo相关配置)
     *
     * @param args
     */
    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }
}
  • 启动zookerper,启动dubbo-admin,这里用于可视化
    12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第19张图片
  • 查看应用
    12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第20张图片

创建springboot-consumer模块:用户业务,作为服务消费者,pom.xml文件中:引入通用模块,可以使用定义的接口

    <dependencies>
        <dependency>
            <groupId>com.springcloudgroupId>
            <artifactId>springboot-commonartifactId>
            <version>1.0-SNAPSHOTversion>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>com.alibaba.bootgroupId>
            <artifactId>dubbo-spring-boot-starterartifactId>
            <version>0.2.0version>
        dependency>
    dependencies>

ConsumerServiceImpl :ConsumerService的实现类, 供远程调用

@Service
public class ConsumerServiceImpl implements ConsumerService {

    /**
     * @param userId
     */
    @Reference
    ProviderService providerService;

    @Override
    public List<UserAddress> initProvider(String userId) {
        //1.查询用户的收获地址
        System.out.println("用户id:" + userId);
        List<UserAddress> addressList = providerService.getUserAddressList(userId);
        return addressList;
    }
}

application.yml:dubbo配置信息

dubbo:
  #应用名
  application:
    name: consumer-service
  #注册中心地址
  registry:
    address: 127.0.0.1:2181
    protocol: zookeeper

server:
  port: 8081

ConsumerApplication启动类

@SpringBootApplication
@EnableDubbo
public class ConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}
  • 启动zookerper,启动dubbo-admin,这里用于可视化
    12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第21张图片
  • 查看应用
    12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第22张图片

5、dubbo配置相关介绍

执行顺序

12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第23张图片

启动时检查

  • 在启动时检查依赖的服务是否可用,Dubbo缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题,默认 check="true"
  • 可以通过 check="false" 关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。

示例:

dubbo.reference.com.foo.BarService.check=false
dubbo.reference.check=false
dubbo.consumer.check=false
dubbo.registry.check=false
  • 关闭某个服务的启动时检查 (没有提供者时报错)
    <dubbo:reference interface="com.foo.BarService" check="false" />
    
  • 关闭所有服务的启动时检查 (没有提供者时报错)
    <dubbo:consumer check="false" />
    
  • 关闭注册中心启动时检查 (注册订阅失败时报错)
    <dubbo:registry check="false" />
    

12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第24张图片

超时设置

  • 服务提供者端睡眠4秒12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第25张图片

  • 然后消费端去请求接口http://localhost:8081/init?id=112、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第26张图片

  • 发现服务提供者已经超时,说明超时有个默认值,默认是1000毫秒12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第27张图片

  • 将超时时间设置为5000,再观察请求结果12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第28张图片

  • 结果成功12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第29张图片

  • 不同粒度配置的覆盖关系

    方法级优先,接口级次之,全局配置再次之。
    如果级别一样,则消费方优先,提供方次之。
    12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第30张图片

重试次数配置

Dubbo 服务在尝试调用一次之后,如出现非业务异常(服务突然不可用、超时等),Dubbo 默认会进行额外的最多2次重试

  • 在消费者配置文件中配置重试次数12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第31张图片
  • 结果12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第32张图片

多版本

Dubbo中为同一个服务配置多个版本,当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用

可以按照以下的步骤进行版本迁移:

  • 在低压力时间段,先升级一半提供者为新版本
  • 再将所有消费者升级为新版本
  • 然后将剩下的一半提供者升级为新版本
    12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第33张图片

6、dubbo高可用

6.1、zookeeper宕机与dubbo直连

现象:zookeeper注册中心宕机,还可以消费dubbo暴露的服务

原因:健壮性

  • 监控中心宕机不影响使用,只是丢失部分采样数据
  • 数据库宕机后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
  • 注册中心集群,任意一台宕掉后,将自动切换到另一台
  • 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
  • 服务提供者无状态,任意一台宕掉后,不影响使用
  • 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复

在这里插入图片描述

6.2、集群下dubbo负载均衡的配置

在集群负载均衡时,Dubbo 提供了多种均衡策略,缺省为 random 随机调用。具体实现上,Dubbo 提供的是客户端负载均衡,即由Consumer通过负载均衡算法得出需要将请求提交到哪个 Provider 实例。

负载均衡策略

算法 特性 备注
RandomLoadBalance 加权随机 默认算法,默认权重相同
RoundRobinLoadBalance 加权轮询 借鉴于 Nginx 的平滑加权轮询算法,默认权重相同
LeastActiveLoadBalance 最少活跃优先 + 加权随机 背后是能者多劳的思想
ShortestResponseLoadBalance 最短响应优先 + 加权随机 更加关注响应速度
ConsistentHashLoadBalance 一致性 Hash 确定的入参,确定的提供者,适用于有状态请求

7、dubbo原理

7.1、RPC原理

12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第34张图片

一次完整的RPC调用流程(同步调用,异步另说)如下

  • 1.服务消费方(client)调用服务(以本地调用方式)
  • 2.client stub(客户端代理)接收到后负责将方法、参数等组装成能够进行网络传输的消息体。
  • 3.client stub(客户端代理)找到服务地址,并通过网络将消息发送到服务端。
  • 4.server stub(服务端代理)收到消息后进行解码
  • 5.server stub(服务端代理)根据解码结果调用本地的服务
  • 6.本地服务执行并结果返回给server stub
  • 7.server stub将返回结果打包成消息并发送至消费方
  • 8.client stub接收到消息,并进行解码
  • 9.服务方得到最终结果

RPC框架的目标就是要2-8这些步骤都封装起来,这些细节对用户来说是透明的,不可见的。

7.2、netty通信原理

Netty是一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。它极大地简化了TCP 和 UDP套接字服务器等网络编程。。

BIO:阻塞式
12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第35张图片
NIO:非阻塞式
12、SpringBoot:分布式 Dubbo +Zookeeper介绍和使用_第36张图片

  • Selector:一般称为选择器,也可以翻译为多路复用器
  • Connect(连接就绪)、Accept(接受就绪)、Read(读就绪)、Write(写就绪)

你可能感兴趣的:(SpringBoot,分布式)