1 Star 0 Fork 165

ElonChung / Java-Review

forked from flatfish / Java-Review 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
Dubbo+Zookeeper+SpringBoot入门篇.md 13.95 KB
一键复制 编辑 原始数据 按行查看 历史
icanci 提交于 2020-09-07 22:34 . :fire:更新文件名

分布式 Dubbo + Zookeeper + SpringBoot

什么是分布式

分布式系统是由一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统。分布式系统的出现是为了用廉价的、普通的机器完成单个计算机无法完成的计算、存储任务。其目的是利用更多的机器,处理更多的数据

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

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

系统的演变

单一应用架构 [单机] -> 垂直应用架构 [MVC] -> 分布式服务架构 [RPC] -> 流动计算架构 [SOA]

RPC

HTTP协议

http协议是基于tcp协议的,tcp协议是流式协议,包头部分可以通过多出的\r\n来分界,包体部分如何分界呢?这是协议本身要解决的问题。目前一般有两种方式,第一种方式就是在包头中有个content-Length字段,这个字段的值的大小标识了POST数据的长度,服务器收到一个数据包后,先从包头解析出这个字段的值,再根据这个值去读取相应长度的作为http协议的包体数据。

RPC

进程间通信(IPC,Inter-Process Communication),指至少两个进程或线程间传送数据或信号的一些技术或方法。进程是计算机系统分配资源的最小单位。每个进程都有自己的一部分独立的系统资源,彼此是隔离的。为了能使不同的进程互相访问资源并进行协调工作,才有了进程间通信。这些进程可以运行在同一计算机上或网络连接的不同计算机上。 进程间通信技术包括消息传递、同步、共享内存和远程过程调用。 IPC是一种标准的Unix通信机制。

729358-839e7a32b598953e

729358-de38e5423ffbc3e7

RPC的核心:通讯、序列化

Dubbo Architecture

architecture

服务提供者(Provider):暴露服务的服务提供方,服务提供者在启动的时候,向注册中心注册自己提供的服务

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

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

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

Zookeeper

官网: https://zookeeper.apache.org/

下载:https://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz

安装:

  • 解压到文件夹即可

  • 然后进入安装目录的 bin 目录下 D:\zookeeper-3.4.14\bin

  • Windows 10 下执行可执行文件 zkServer.cmd

  • 如果发现闪退,则解决方案如下

    • # zkServer.cmd 源文件
      @echo off
      REM Licensed to the Apache Software Foundation (ASF) under one or more
      REM contributor license agreements.  See the NOTICE file distributed with
      REM this work for additional information regarding copyright ownership.
      REM The ASF licenses this file to You under the Apache License, Version 2.0
      REM (the "License"); you may not use this file except in compliance with
      REM the License.  You may obtain a copy of the License at
      REM
      REM     http://www.apache.org/licenses/LICENSE-2.0
      REM
      REM Unless required by applicable law or agreed to in writing, software
      REM distributed under the License is distributed on an "AS IS" BASIS,
      REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      REM See the License for the specific language governing permissions and
      REM limitations under the License.
      
      setlocal
      call "%~dp0zkEnv.cmd"
      
      set ZOOMAIN=org.apache.zookeeper.server.quorum.QuorumPeerMain
      echo on
      call %JAVA% "-Dzookeeper.log.dir=%ZOO_LOG_DIR%" "-Dzookeeper.root.logger=%ZOO_LOG4J_PROP%" -cp "%CLASSPATH%" %ZOOMAIN% "%ZOOCFG%" %*
      pause
      endlocal
    • 在倒数第二行增加 pause暂停运行,观察错误信息

    • 2020-07-12 20:24:14,524 [myid:] - ERROR [main:QuorumPeerMain@88] - Invalid config, exiting abnormally
      org.apache.zookeeper.server.quorum.QuorumPeerConfig$ConfigException: Error processing D:\zookeeper-3.4.14\bin\..\conf\zoo.cfg
    • 缺少文件,添加 zoo.cfg 如下

    • # The number of milliseconds of each tick
      tickTime=2000
      # The number of ticks that the initial 
      # synchronization phase can take
      initLimit=10
      # The number of ticks that can pass between 
      # sending a request and getting an acknowledgement
      syncLimit=5
      # the directory where the snapshot is stored.
      # do not use /tmp for storage, /tmp here is just 
      # example sakes.
      dataDir=/tmp/zookeeper
      # the port at which the clients will connect
      clientPort=2181
      # the maximum number of client connections.
      # increase this if you need to handle more clients
      #maxClientCnxns=60
      #
      # Be sure to read the maintenance section of the 
      # administrator guide before turning on autopurge.
      #
      # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
      #
      # The number of snapshots to retain in dataDir
      #autopurge.snapRetainCount=3
      # Purge task interval in hours
      # Set to "0" to disable auto purge feature
      #autopurge.purgeInterval=1
    • 通过配置文件可以看到重要的位置

      • dataDir=./ 临时数据存储的目录 (可写相对路径)
      • clientPort=2181 Zookeeper默认端口号
      • 双击打开:zkCli.cmd 是Zookeeper的客户端

Dubbo环境搭建

官网: http://dubbo.apache.org/zh-cn/index.html

下载:[Dubbo-Admin] https://github.com/apache/dubbo-admin.git

可以使用加速器: http://g.widyun.com/

安装:

  • 下载 master 之后解压即可

  • 修改配置文件中 Zookeeper 的地址 D:\dubbo-admin-master\dubbo-admin\src\main\resources\application.properties

  • # 注册中心的地址
    dubbo.registry.address=zookeeper://127.0.0.1:2181
  • 然后在项目目录下打包 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
  • 登录页面如下

  • 1594558879548

  • dubbo-admin:是一个监控管理网站 查看我们注册了哪些服务,哪些服务被消费了

  • dubbo : jar包

SpringBoot + Dubbo + Zookeeper

  • 初始化一个空项目
provider-server 提供者模块
  • 添加提供者服务 provider-server 模块,引用依赖如下

  • <!-- 导入依赖 Dubbo -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.7</version>
    </dependency>
    
    <!-- 导入依赖 zkclient -->
    <dependency>
        <groupId>com.github.sgroschupf</groupId>
        <artifactId>zkclient</artifactId>
        <version>0.1</version>
    </dependency>
    
    <!-- 日志会冲突 -->
    <!-- 引入Zookeeper -->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>2.12.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>2.12.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>3.4.8</version>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
  • 编写Service代码

  • public interface TicketService {
        public String getTicket ();
    }
    
    @Service  // 可以被扫描到,在项目启动就注册到注册自中心
    @Component //使用了Dubbo之后 尽量不要使用Service
    public class TicketServiceImpl implements TicketService {
        @Override
        public String getTicket() {
            return "java";
        }
    }
  • 编写配置文件

  • spring.application.name=provider-server
    # 应用服务 WEB 访问端口
    server.port=8080
    
    # 服务应用名字
    dubbo.application.name=provider-server
    # 注册中心地址
    dubbo.registry.address=zookeeper://127.0.0.1:2181
    # 哪些服务要注册
    dubbo.scan.base-packages=cn.icanci.provider.service
    debug=true
  • 然后启动Zookeeper和Dubbo 启动 provider-server服务

  • 浏览器输入 http://localhost:7001/可查看开启的提供者服务

  • 1594562459764

  • 1594562491866

consumer-server 消费者模块
  • 添加 consumer-server 消费者模块,导入依赖

  • <!-- 导入依赖 Dubbo -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.7</version>
    </dependency>
    
    <!-- 导入依赖 zkclient -->
    <dependency>
        <groupId>com.github.sgroschupf</groupId>
        <artifactId>zkclient</artifactId>
        <version>0.1</version>
    </dependency>
    
    <!-- 日志会冲突 -->
    <!-- 引入Zookeeper -->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>2.12.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>2.12.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>3.4.8</version>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
  • 编写Service代码

  • package cn.icanci.consumer.service;
    
    import cn.icanci.provider.service.TicketService;
    import org.apache.dubbo.config.annotation.Reference;
    import org.springframework.stereotype.Service;
    
    @Service
    public class UserService {
        // 想拿到 provider-service 提供的票,要去注册中心拿到服务
        // 引用 Pom 坐标,可以定义路径相同的接口名
        @Reference
        TicketService ticketService;
    
        public void buyTicket(){
            String ticket = ticketService.getTicket();
            System.out.println(ticket);
        }
    }
  • 注意点 上述 定义路径相同的接口名 必须是完全一致的名称

  • provider-server 包路径:cn.icanci.provider.service
    consumer-server 包路径:cn.icanci.consumer.service
    
    此时如果使得上述生效,即consumer-server可以调用provider-server中的服务
    必须在consumer-server中创建cn.icanci.provider.service,否则会报错
    具体参见下图:
  • 1594562967589

  • 添加配置

  • spring.application.name=consumer-server
    # 应用服务 WEB 访问端口
    server.port=8181
    
    # 消费者去哪里拿服务
    dubbo.application.name=consumer-server
    # 注册中心的地址
    dubbo.registry.address=zookeeper://127.0.0.1:2181
  • 进行测试

  • @SpringBootTest
    class ConsumerServerApplicationTests {
    
        @Autowired
        private UserService userService;
        @Test
        void contextLoads() {
            System.out.println(userService);
            userService.buyTicket();
        }
    }
  • 测试结果如下

  • 1594563055053

总结

Dubbo + Zookeeper + SpringBoot 的整合还是比较麻烦的,配置项目很多

微服务架构会遇到的4个核心问题
这么多服务,客户端怎么去访问?
这么多服务,服务之前应该如何通信?
这么多服务,如何治理?
服务挂了怎么办?
解决方案
SpringCloud,是一套生态,就是来解决以上分布式架构的4个问题

想使用SpringCloud,必须掌握SpringBoot,SpringCloud基于SpringBoot

Spring Cloud NetFlix,提出了一套解决方案 一站式解决方案,我们都可以去用

API网关:Zuul组件

HTTP通信:Feign --> HttpClient --> HTTP的通信方式,同步并阻塞

服务注册于发现:Eureka

熔断机制:Hystrix

2018年,NetFlix宣布无限期停止维护,生态不在维护,就会脱节。

Apache Dubbo Zookeeper

API网关:没有,要么找第三方组件,要么自己实现

Dubbo:是一个高性能的RPC框架,基于Java实现的,通信问题

Zookeeper:服务注册于发现 (Hadoop,Hive)

熔断机制:借助了Hystrix

SpringCloud Alibaba 一站式解决方案
又提出了方案,服务网格:下一代微服务标准

Server Mesh

代表解决方案:istio

万变不离其宗

API网关

RPC、HTTP框架

服务注册与发现,高可用

熔断机制,服务降级

为什么要解决这个问题:网络是不可靠的

1
https://gitee.com/elonchung/Java-Review.git
git@gitee.com:elonchung/Java-Review.git
elonchung
Java-Review
Java-Review
master

搜索帮助