SpringCloud之zookeeper替换Eureka

前提

在我们的之前项目中已经搭建了一个消费者一个服务者;通过Eureka作为注册中心来完成服务调用,但是Netflix 官方已经宣布不再维护 eureka了,所以现在很多公司已经用其他的注册中心来替换eureka;这次我们使用zookeeper 来替换eureak

zookeeper的安装

zookeeper和eureka不同,eureka是需要自己部署服务的,而zookeeper是自己安装的;这里学习需要暂时使用的 下载后windows版本使用

  1. 官网下载
    zookeeper3.58
    点击进入后可以选择下载
    在这里插入图片描述

  2. 解压
    可以选择下载,下载的是一个.tar.gz ;解压两次就可以了,下载完成后
    将conf目录下的zoo_sample.cfg文件,复制一份,重命名为zoo.cfg
    在这里插入图片描述

修改zoo.cfg配置文件,将dataDir=/tmp/zookeeper修改成zookeeper安装目录所在的data文件夹(需要在安装目录下面新建一个空的data文件夹和log文件夹),再添加一条添加数据日志的配置,如下图
在这里插入图片描述
在这里插入图片描述

  1. 启动zookeeper
    启动zookeeper,判定是否安装成功,双击运行bin目录下的zkServer.cmd文件即可
    在这里插入图片描述
    检查服务是否启动,可以通过 netstat -ano 命令查看是否有你配置的 clientPort 端口号在监听服务;

也可以通过双击执行zkCli.cmd来判定是否启动成功。
在这里插入图片描述
连接成功:
在这里插入图片描述
连接失败:
在这里插入图片描述
Intelij IDEA中添加zookeeper插件
在这里插入图片描述
点击工具栏的“设置”图标,在弹出的窗口中,选择Plugins插件选项,搜索zookeeper进行相应安装
在这里插入图片描述
重启IDEA开发工具后,查看是否安装成功

zookeeper的介绍

在这里插入图片描述
zookeeper的作用和eureka相似都是注册中心的使用,但是zookeeper除了注册中心还可以有其他的作用,比如:分布式应用程序可以基于 ZooKeeper 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、配置维护,名字服务、分布式同步、分布式锁和分布式队列
等功能。

zookeeper的结构

Zookeeper维护一个类似文件系统的数据结构:
在这里插入图片描述
每个子目录项如 NameService 都被称作为 znode(目录节点),和文件系统一样,我们能够自由的增加、删除znode,在一个znode下增加、删除子znode,唯一的不同在于znode是可以存储数据的。

有四种类型的znode:

  1. PERSISTENT-持久化目录节点

客户端与zookeeper断开连接后,该节点依旧存在

  1. PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点

客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号

  1. EPHEMERAL-临时目录节点

客户端与zookeeper断开连接后,该节点被删除

  1. EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点

客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号

zookeeper的配置文件

配置参数解读

解读zoo.cfg 文件中参数含义

1)tickTime:通信心跳数,Zookeeper服务器心跳时间,单位毫秒

Zookeeper使用的基本时间,服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个tickTime时间就会发送一个心跳,时间单位为毫秒。

它用于心跳机制,并且设置最小的session超时时间为两倍心跳时间。(session的最小超时时间是2*tickTime)

2)initLimit:LF初始通信时限

集群中的follower跟随者服务器(F)与leader领导者服务器(L)之间初始连接时能容忍的最多心跳数(tickTime的数量),用它来限定集群中的Zookeeper服务器连接到Leader的时限。

投票选举新leader的初始化时间

Follower在启动过程中,会从Leader同步所有最新数据,然后确定自己能够对外服务的起始状态。

Leader允许F在initLimit时间内完成这个工作。

3)syncLimit:LF同步通信时限

集群中Leader与Follower之间的最大响应时间单位,假如响应超过syncLimit * tickTime,

Leader认为Follwer死掉,从服务器列表中删除Follwer。

在运行过程中,Leader负责与ZK集群中所有机器进行通信,例如通过一些心跳检测机制,来检测机器的存活状态。

如果L发出心跳包在syncLimit之后,还没有从F那收到响应,那么就认为这个F已经不在线了。

4)dataDir:数据文件目录+数据持久化路径保存内存数据库快照信息的位置,如果没有其他说明,更新的事务日志也保存到数据库。

5)clientPort:客户端连接端口监听客户端连接的端口

zookeeper的应用场景

数据发布与订阅(配置中心)

数据发布与订阅,即所谓的配置中心,顾名思义就是发布者将数据发布到 ZooKeeper 节点上,
供订阅者进行数据订阅,进而达到动态获取数据的目的,实现配置信息的集中式管理和动态更新。

对于:数据量通常比较小。数据内容在运行时动态变化。集群中各机器共享,配置一致。
这样的全局配置信息就可以发布到 ZooKeeper上,让客户端(集群的机器)去订阅该消息。

发布/订阅系统一般有两种设计模式,分别是推(Push)和拉(Pull)模式。
- 推模式
服务端主动将数据更新发送给所有订阅的客户端
- 拉模式
客户端主动发起请求来获取最新数据,通常客户端都采用定时轮询拉取的方式

ZooKeeper 采用的是推拉相结合的方式:
客户端想服务端注册自己需要关注的节点,一旦该节点的数据发生变更,那么服务端就会向相应
的客户端发送Watcher事件通知,客户端接收到这个消息通知后,需要主动到服务端获取最新的数据

命名服务

命名服务也是分布式系统中比较常见的一类场景。在分布式系统中,通过使用命名服务,客户端
应用能够根据指定名字来获取资源或服务的地址,提供者等信息。被命名的实体通常可以是集群中的
机器,提供的服务,远程对象等等——这些我们都可以统称他们为名字。

其中较为常见的就是一些分布式服务框架(如RPC)中的服务地址列表。通过在ZooKeepr里
创建顺序节点,能够很容易创建一个全局唯一的路径,这个路径就可以作为一个名字。

ZooKeeper 的命名服务即生成全局唯一的ID。
ZooKeeper 中特有 Watcher 注册与异步通知机制,能够很好的实现分布式环境下不同机器,
甚至不同系统之间的通知与协调,从而实现对数据变更的实时处理。使用方法通常是不同的客户端
如果 机器节点 发生了变化,那么所有订阅的客户端都能够接收到相应的Watcher通知,并做出相应
的处理。

ZooKeeper的分布式协调/通知,是一种通用的分布式系统机器间的通信方式。

Master选举

针对 Master 选举的需求,通常情况下,我们可以选择常见的关系型数据库中的主键特性来
实现:希望成为 Master 的机器都向数据库中插入一条相同主键ID的记录,数据库会帮我们进行
主键冲突检查,也就是说,只有一台机器能插入成功——那么,我们就认为向数据库中成功插入数据
的客户端机器成为Master。

依靠关系型数据库的主键特性确实能够很好地保证在集群中选举出唯一的一个Master。

但是,如果当前选举出的 Master 挂了,那么该如何处理?谁来告诉我 Master 挂了呢?

显然,关系型数据库无法通知我们这个事件。但是,ZooKeeper 可以做到!

利用 ZooKeepr 的强一致性,能够很好地保证在分布式高并发情况下节点的创建一定能够

保证全局唯一性,即 ZooKeeper 将会保证客户端无法创建一个已经存在的 数据单元节点。
也就是说,如果同时有多个客户端请求创建同一个临时节点,那么最终一定只有一个客户端
请求能够创建成功。利用这个特性,就能很容易地在分布式环境中进行 Master 选举了。

成功创建该节点的客户端所在的机器就成为了 Master。同时,其他没有成功创建该节点的

客户端,都会在该节点上注册一个子节点变更的 Watcher,用于监控当前 Master 机器是否存
活,一旦发现当前的Master挂了,那么其他客户端将会重新进行 Master 选举。

这样就实现了 Master 的动态选举。

分布式锁

分布式锁是控制分布式系统之间同步访问共享资源的一种方式
分布式锁又分为排他锁和共享锁两种

排它锁
ZooKeeper如何实现排它锁?

定义锁
ZooKeeper 上的一个 机器节点 可以表示一个锁
获得锁
把ZooKeeper上的一个节点看作是一个锁,获得锁就通过创建临时节点的方式来实现。
ZooKeeper 会保证在所有客户端中,最终只有一个客户端能够创建成功,那么就可以
认为该客户端获得了锁。同时,所有没有获取到锁的客户端就需要到/exclusive_lock
节点上注册一个子节点变更的Watcher监听,以便实时监听到lock节点的变更情况。
释放锁
因为锁是一个临时节点,释放锁有两种方式

当前获得锁的客户端机器发生宕机或重启,那么该临时节点就会被删除,释放锁
正常执行完业务逻辑后,客户端就会主动将自己创建的临时节点删除,释放锁。
无论在什么情况下移除了lock节点,ZooKeeper 都会通知所有在 /exclusive_lock 节点上注册了节点变更 Watcher 监听的客户端。这些客户端在接收到通知后,再次重新发起分布式锁获取,即重复『获取锁』过程。

共享锁

共享锁在同一个进程中很容易实现,但是在跨进程或者在不同 Server 之间就不好实现了。Zookeeper 却很容易实现这个功能,实现方式也是需要获得锁的 Server 创建一个 EPHEMERAL_SEQUENTIAL 目录节点,然后调用 getChildren方法获取当前的目录节点列表中最小的目录节点是不是就是自己创建的目录节点,如果正是自己创建的,那么它就获得了这个锁,如果不是那么它就调用 exists(String path, boolean watch) 方法并监控 Zookeeper 上目录节点列表的变化,一直到自己创建的节点是列表中最小编号的目录节点,从而获得锁,释放锁很简单,只要删除前面它自己所创建的目录节点就行了

分布式协调服务/通知

ZooKeeper 中特有 Watcher 注册与异步通知机制,能够很好的实现分布式环境下不同机器,
甚至不同系统之间的通知与协调,从而实现对数据变更的实时处理。使用方法通常是不同的客户端
如果 机器节点 发生了变化,那么所有订阅的客户端都能够接收到相应的Watcher通知,并做出相应
的处理。

ZooKeeper的分布式协调/通知,是一种通用的分布式系统机器间的通信方式。

zookeeper替换Eureka

和我们之前需要搭建eureka服务不同,zookeeper是需要安装的,在安装好以后,直接访问即可,无需配置

改造服务者

这里改造服务者和消费者的方法其实是相同的,在我们之前都是通过springcloud的注册中心配置来获取注册中心的信息,即是使用注解@EnableDiscoveryClient 和 DiscoveryClient 来获取注册中心的信息的;所以我们不需要修改代码什么的;

  1. 修改pom
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
        </dependency>
  1. 配置修改
server:
  port: 8082
spring:
  application:
    name: consumer # 应用名称
  cloud:
    zookeeper:
       connect-string: 127.0.0.1:2181
  1. 启动测试
    启动测试后会发现,和原有的没有区别

注意:
如果在启动时候发现这样的错误提示的话,那么代码引入的依赖和使用的zookeeper版本不一致报错,所以建议修改依赖或者更换zookeeper版本

org.apache.zookeeper.KeeperException$UnimplementedException: KeeperErrorCode = Unimplemented for /services/user-service/8ca83364-b3af-47e3-b6d7-266d190bef89

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值