SpringBoot 学习(十)分布式理论

12. 分布式理论

12.1 简介

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

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

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

    ​ —— 张鹏飞

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

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

12.2 Dubbo

(1) 背景

● 架构

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

SpringBoot 学习(十)分布式理论_第1张图片

单一应用架构(All in One)

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

垂直应用架构(Vertical Application)

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

分布式服务架构(Distributed Service)

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

流动计算架构(Elastic Computing)

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

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

  • 本地过程调用

    直接调用,函数体通过函数指针来指定。
    SpringBoot 学习(十)分布式理论_第2张图片

  • 远程过程调用

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

    SpringBoot 学习(十)分布式理论_第3张图片

(2) 概念

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

SpringBoot 学习(十)分布式理论_第4张图片

  • 节点角色说明
节点 角色说明
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
    
  • 在项目目录下打包 dubbo-admin

    mvn clean package -Dmaven. test. skip=true

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

    SpringBoot 学习(十)分布式理论_第5张图片

    SpringBoot 学习(十)分布式理论_第6张图片

(4) 测试

  • 启动 zookeeper

  • 启动 dubbo

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

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

SpringBoot 学习(十)分布式理论_第7张图片

12.3 Zookepper

● 简介

  • ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
  • 下载地址:http://zookeeper.apache.org/releases.html#download

● 启动服务

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

  • 服务闪退问题

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

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

      SpringBoot 学习(十)分布式理论_第8张图片

    • 程序未找到 zoo.cfg

      SpringBoot 学习(十)分布式理论_第9张图片

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

      SpringBoot 学习(十)分布式理论_第10张图片

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

      SpringBoot 学习(十)分布式理论_第11张图片

    • 测试

      • 打开用户端 bin/zkCli.cmd

        SpringBoot 学习(十)分布式理论_第12张图片

        SpringBoot 学习(十)分布式理论_第13张图片

        SpringBoot 学习(十)分布式理论_第14张图片

12.4 springboot+dubbo+zookeeper

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

SpringBoot 学习(十)分布式理论_第15张图片

(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>
# 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
// service
public interface TicketService {
    public String getTicket();
}
// service
// zookeeper:服务注册与发现
// 项目已启动就自动注册到注册中心
// 注意使用 dubbo 的 Service 注解
@Service
@Component
public class TicketServiceImpl implements TicketService {
    @Override
    public String getTicket() {
        return "Train Ticket";
    }
}
● 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>
# application.properties
server.port=8002

# 消费者取服务,需要暴露自己的名字
dubbo.application.name=consumer-server
# 注册中心的地址,即取服务的地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
// service
public interface UserService {
    public void buyTick();
}
// 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);
    }
}
// service
public interface TicketService {
    public String getTicket();
}
● 启动服务
  • 启动 zkService

  • 启动 dubbo-admin 程序

  • 启动 provider-server 服务

    SpringBoot 学习(十)分布式理论_第16张图片

    SpringBoot 学习(十)分布式理论_第17张图片

    SpringBoot 学习(十)分布式理论_第18张图片

  • 编写并启动 consumer-server 测试

    @Test
    void testBuyTick() {
       userService.buyTick();
    }
    

    在这里插入图片描述

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

    SpringBoot 学习(十)分布式理论_第19张图片

你可能感兴趣的:(SpringBoot,spring,boot,学习,分布式)