• SpringBoot 学习(十)分布式理论


    12. 分布式理论

    12.1 简介

    • 分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统。

    • 分布式是一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统,其目的是利用更多的机器,处理更多的数据。

    • 小饭店原来只有一个厨师,切菜洗菜备料炒菜全干。后来客人多了,厨房一个厨师忙不过来,又请了个厨师,两个厨师都能炒一样的菜,这两个厨师的关系是集群。为了让厨师专心炒菜,把菜做到极致,又请了个配菜师负责切菜,备菜,备料,厨师和配菜师的关系是分布式,一个配菜师也忙不过来了,又请了个配菜师,两个配菜师关系是集群。

      —— 张鹏飞

    • 分布式架构四个核心问题

      • 多服务,客户端如何访问?— API 网关,服务路由
      • 多个服务之间如何通信?— HTTP,RPC框架,异步调用
      • 多服务如何治理?— 服务注册与发现,高可用
      • 服务挂了,怎么办?— 熔断机制,服务降级

    12.2 Dubbo

    (1) 背景

    ● 架构

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

    在这里插入图片描述

    单一应用架构(All in One)

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

    垂直应用架构(Vertical Application)

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

    分布式服务架构(Distributed Service)

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

    流动计算架构(Elastic Computing)

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

    ● RPC
    • RPC(Remote Procedure Call)远程过程调用,简单的理解是一个节点请求另一个节点提供的服务

    • 本地过程调用

      直接调用,函数体通过函数指针来指定。
      在这里插入图片描述

    • 远程过程调用

      // Client端 
      1. 将调用映射为 (函数,进程 ID)。
      2. 将 (函数,进程 ID) 序列化,以二进制形式打包
      3. 把 2 中得到的数据包发送给 Server,这需要使用网络传输层
      4. 等待服务器返回结果
      5. 如果服务器调用成功,那么就将结果反序列化.
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      // Server端
      1. 在本地维护 (函数,进程ID) 到函数指针的映射,可以用 Map map
      2. 等待客户端请求
      3. 得到一个请求后,将其数据包反序列化,得到 (函数,进程ID)
      4. 通过在 map 中查找,得到相应的函数指针
      5. 本地调用函数,得到结果
      6. 将结果序列化后通过网络返回给 Client
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

      在这里插入图片描述

    (2) 概念

    • Dubbo 是一个高性能优秀的服务框架,它使应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring 框架无缝集成。

    在这里插入图片描述

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

    (3) 安装

    • 下载地址:apache/dubbo-admin at master (github.com)

    • 指定 zookeeper 注册地址

      # dubbo-admin-master-0.2.0\dubbo-admin\src\main\resources\application.properties
      server.port=7001
      spring.velocity.cache=false
      spring.velocity.charset=UTF-8
      spring.velocity.layout-url=/templates/default.vm
      spring.messages.fallback-to-system-locale=false
      spring.messages.basename=i18n/message
      spring.root.password=root
      spring.guest.password=guest
      # 注册地址
      dubbo.registry.address=zookeeper://127.0.0.1:2181
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • 在项目目录下打包 dubbo-admin

      mvn clean package -Dmaven. test. skip=true

      • 配置 maven 的环境变量
      • 以管理员身份运行 cmd
      • 在 dubbo 目录下运行cmd,执行命令

      在这里插入图片描述

      在这里插入图片描述

    (4) 测试

    • 启动 zookeeper

    • 启动 dubbo

      java -jar dubbo-admin-0.0.1-SNAPSHOT.jar

    • 浏览器访问 http://localhost:7001/,默认用户名和密码都为 root

    在这里插入图片描述

    12.3 Zookepper

    ● 简介

    ● 启动服务

    • 以管理员身份运行 zkService.cmd

    • 服务闪退问题

      • 没有配置 zoo.cfg 配置文件
    • 解决方案

      • 编辑 zkService.cmd 文件,末尾添加 pause ,暂停服务,便于查找错误。

        在这里插入图片描述

      • 程序未找到 zoo.cfg

        在这里插入图片描述

      • 复制 conf/zoo_sample.cfg 改名为 zoo.cfg

        在这里插入图片描述

      • 再次以管理员身份启动 zkService.cmd

        在这里插入图片描述

      • 测试

        • 打开用户端 bin/zkCli.cmd

          在这里插入图片描述

          在这里插入图片描述

          在这里插入图片描述

    12.4 springboot+dubbo+zookeeper

    (1) 建立空工程,创建两个 springboot 服务模块

    在这里插入图片描述

    (2) 为模块添加服务

    ● provider-server
    
    
    <dependency>
       <groupId>org.apache.dubbogroupId>
       <artifactId>dubbo-spring-boot-starterartifactId>
       <version>2.7.3version>
    dependency>
    
    
    
    <dependency>
       <groupId>com.github.sgroschupfgroupId>
       <artifactId>zkclientartifactId>
       <version>0.1version>
    dependency>
    
    
    <dependency>
       <groupId>org.apache.curatorgroupId>
       <artifactId>curator-frameworkartifactId>
       <version>4.1.0version>
    dependency>
    
    
    <dependency>
       <groupId>org.apache.curatorgroupId>
       <artifactId>curator-recipesartifactId>
       <version>4.2.0version>
    dependency>
    
    <dependency>
       <groupId>org.apache.zookeepergroupId>
       <artifactId>zookeeperartifactId>
       <version>3.4.14version>
       
       <exclusions>
          <exclusion>
             <groupId>org.slf4jgroupId>
             <artifactId>slf4j-log4j12artifactId>
          exclusion>
       exclusions>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    # application.properties
    server.port=8001
    
    # 服务应用名字
    dubbo.application.name=provider-server
    # 注册中心地址,即存放服务的地址
    dubbo.registry.address=zookeeper://127.0.0.1:2181
    # 待注册的服务
    dubbo.scan.base-packages=com.why.service
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    // service
    public interface TicketService {
        public String getTicket();
    }
    
    • 1
    • 2
    • 3
    • 4
    // service
    // zookeeper:服务注册与发现
    // 项目已启动就自动注册到注册中心
    // 注意使用 dubbo 的 Service 注解
    @Service
    @Component
    public class TicketServiceImpl implements TicketService {
        @Override
        public String getTicket() {
            return "Train Ticket";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    ● consumer-server
    
    
    <dependency>
       <groupId>org.apache.dubbogroupId>
       <artifactId>dubbo-spring-boot-starterartifactId>
       <version>2.7.3version>
    dependency>
    
    
    
    <dependency>
       <groupId>com.github.sgroschupfgroupId>
       <artifactId>zkclientartifactId>
       <version>0.1version>
    dependency>
    
    
    <dependency>
       <groupId>org.apache.curatorgroupId>
       <artifactId>curator-frameworkartifactId>
       <version>4.1.0version>
    dependency>
    
    
    <dependency>
       <groupId>org.apache.curatorgroupId>
       <artifactId>curator-recipesartifactId>
       <version>4.2.0version>
    dependency>
    
    <dependency>
       <groupId>org.apache.zookeepergroupId>
       <artifactId>zookeeperartifactId>
       <version>3.4.14version>
       
       <exclusions>
          <exclusion>
             <groupId>org.slf4jgroupId>
             <artifactId>slf4j-log4j12artifactId>
          exclusion>
       exclusions>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    # application.properties
    server.port=8002
    
    # 消费者取服务,需要暴露自己的名字
    dubbo.application.name=consumer-server
    # 注册中心的地址,即取服务的地址
    dubbo.registry.address=zookeeper://127.0.0.1:2181
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    // service
    public interface UserService {
        public void buyTick();
    }
    
    • 1
    • 2
    • 3
    • 4
    // service
    // 此处的 @Service 是将实现类注册到 Spring 中,注意导包路径
    @Service
    public class UserServiceImpl implements UserService {
    
        // 在注册中心拿到 provider-server 的服务
        // 本地可定义与 provider-server 端路径相同的接口,使用 @Reference 引用 provider-server 端注册在注册中心的服务
        @Reference
        private TicketService ticketService;
    
        @Override
        public void buyTick() {
            String ticket = ticketService.getTicket();
            System.out.println("在注册中心拿到=>" + ticket);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    // service
    public interface TicketService {
        public String getTicket();
    }
    
    • 1
    • 2
    • 3
    • 4
    ● 启动服务
    • 启动 zkService

    • 启动 dubbo-admin 程序

    • 启动 provider-server 服务

      在这里插入图片描述

      在这里插入图片描述

      在这里插入图片描述

    • 编写并启动 consumer-server 测试

      @Test
      void testBuyTick() {
         userService.buyTick();
      }
      
      • 1
      • 2
      • 3
      • 4

      在这里插入图片描述

      consumer-server 服务并未编写实现类实现 TicketService 接口,此为 consumer-server 在注册中心拿到的结果。即执行了如下过程:

      在这里插入图片描述

  • 相关阅读:
    Java8中Stream详细用法大全
    基于深度学习网络的烟雾检测算法matlab仿真
    【Linux】环境变量
    大数据-玩转数据-DataWorks调度参数概述
    阿里云核心产品list
    flutter系列之:Material中的3D组件Card
    【重识云原生】第六章容器6.1.5节——Docker核心技术Namespace
    FPGA高端项目:FPGA基于GS2971+GS2972架构的SDI视频收发+图像缩放,提供3套工程源码和技术支持
    个人玩航拍,如何申请无人机空域?
    腾讯云精彩亮相 2023 长沙·中国 1024 程序员节,共创数智未来!
  • 原文地址:https://blog.csdn.net/qq_42651415/article/details/133273659