Springboot测试ZookeeperClient连接ZK

zk简介:

简介
ZooKeeper是一个开源的分布式协调服务,由雅虎创建,是 Google Chubby 
的开源实现。分布式应用程序可以基于 ZooKeeper 实现诸如数据发布/订阅、
负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式
锁和分布式队列等功能


集群角色:
Leader
Follower
Observer
一个 ZooKeeper 集群同一时刻只会有一个 Leader,其他都是 Follower
 或 Observer。


会话:
Session 是指客户端会话,一个客户端连接是指客户端和 ZooKeeper 
服务器之间的TCP长连接,
从第一次连接建立开始,客户端会话的生命周期也开始了,通过这个连
接,客户端能够通过心跳检测和服务器保持有效的会话,也能够向 ZooKeeper
 服务器发送请求并接受响应,同时还能通过该连接接收来自服务器的
 Watch 事件通知。


数据节点:
ZooKeeper 中的数据节点是指数据模型中的数据单元,称为 ZNode。
ZooKeeper 将所有数据存储在内存中,数据模型是一棵树(ZNode Tree),
由斜杠(/)进行分割的路径,就是一个ZNode,如 /hbase/master,其中
 hbase 和 master 都是 ZNode。每个 ZNode 上都会保存自己的数据内容,
同时会保存一系列属性信息。

节点类型:
持久节点
临时节点

版本:
ZooKeeper 的每个 ZNode 上都会存储数据,对应于每个 ZNode,ZooKeeper
 都会为其维护一个叫作 Stat 的数据结构,Stat 中记录了这个 ZNode 的三
个数据版本,分别是 version(当前ZNode的版本)、cversion(当前ZNode子
节点的版本)和 aversion(当前 ZNode 的 ACL 版本)

状态信息:
每个 ZNode 除了存储数据内容之外,还存储了 ZNode 本身的一些状态信息。
用 get 命令可以同时获得某个 ZNode 的内容和状态信息。

Zookeeper-特性介绍

最终一致性 可靠性 实时性 等待无关 原子性 顺序性

事务操作

 在ZooKeeper中,能改变ZooKeeper服务器状态的操作称为事务操作。
一般包括数据节点创建与删除、数据内容更新和客户端会话创建与失效等操作
。对应每一个事务请求,ZooKeeper 都会为其分配一个全局唯一的事务ID,
用 ZXID 表示,通常是一个64位的数字。每一个 ZXID 对应一次更新操作,
从这些 ZXID 中可以间接地识别出 ZooKeeper 处理这些事务操作请求的
全局顺序

Zookeeper-基本概念:

Watcher
Watcher(事件监听器),是 ZooKeeper 中一个很重要的特性。ZooKeeper允许
用户在指定节点上注册一些 Watcher,并且在一些特定事件触发的时候,ZooKeeper
 服务端会将事件通知到感兴趣的客户端上去。该机制是 ZooKeeper 实现分布式协
调服务的重要特性。

Acl ZooKeeper 采用 ACL(Access Control Lists)策略来进行权限控制。

ZooKeeper 定义了如下5种权限:     

CREATE: 创建子节点的权限     

READ: 获取节点数据和子节点列表的权限     

WRITE:更新节点数据的权限     

DELETE: 删除子节点的权限   

 ADMIN: 设置节点ACL的权限

Zookeeper-工作原理:

Zookeeper 的核心是原子广播,这个机制保证了各个Server之间的同步。
实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复
模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab
就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和 leader
的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有
相同的系统状态。

Zookeeper- Server工作状态:

LOOKING LEADING FOLLOWING

Zookeeper- Paxos算法

分布式一致性算法(Consensus Algorithm)是一个分布式计算领域的基础性
问题,其最基本的功能是为了在多个进程之间对某个(某些)值达成一致(强
一致);进而解决分布式系统的可用性问题(高可用)。Paxos是最重要的分
布式一致性算法,很多人都把它作为“分布式一致性协议”的代名词(Mike Burrows,
 inventor of the Chubby service at Google, says that“there is only 
one consensus protocol, and that’s Paxos”)。

Zookeeper-选举流程(basic paxos):

当leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,
恢复模式需要重新选举出一个新的leader,让所有的Server都恢复到一个正
确的状态。Zk的选举算法有两种:一种是基于basic paxos实现的,另外一
种是基于fast paxos算法实现的。系统默认的选举算法为fast paxos。

同步流程:

选完Leader以后,zk就进入状态同步过程。
Leader等待server连接
Follower连接leader,将最大的zxid发送给leader
Leader根据follower的zxid确定同步点
完成同步后通知follower 已经成为uptodate状态
Follower收到uptodate消息后,又可以重新接受client的请求进行服务了

Zookeeper-Leader工作流程:

恢复数据
维持与Learner的心跳,接收Learner请求并判断Learner的请求消息类型
Learner的消息类型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE
消息,根据不同的消息类型,进行不同的处理

Zookeeper-Follower工作流程

向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息)
接收Leader消息并进行处理
接收Client的请求,如果为写请求,发送给Leader进行投票
返回Client结果

 

 

引入jar包:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.cc</groupId>
	<artifactId>springboot-zookeeper-client</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>springboot-zookeeper-client</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.13.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>


		<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
			<version>3.4.13</version>
			<exclusions>
				<exclusion>
					<artifactId>log4j</artifactId>
					<groupId>log4j</groupId>
				</exclusion>
				<exclusion>
					<artifactId>slf4j-log4j12</artifactId>
					<groupId>org.slf4j</groupId>
				</exclusion>
			</exclusions>
		</dependency>

		<!-- https://mvnrepository.com/artifact/com.101tec/zkclient -->
		<dependency>
			<groupId>com.101tec</groupId>
			<artifactId>zkclient</artifactId>
			<version>0.10</version>
		</dependency>


		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>


		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>

测试单机client:

package com.cc.springbootzookeeperclient;

import lombok.extern.slf4j.Slf4j;
import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.ZkConnection;
import org.apache.zookeeper.CreateMode;

import java.util.List;

/**
 * Created by CarlosXiao on 2018/7/28.
 */
@Slf4j
public class ZkClientTest {

    public static final String ZK_HOST = "192.168.13.51:2182,192.168.13.51:2183,192.168.13.51:2184,192.168.13.51:2185";

    public static void main(String [] args) throws InterruptedException {
        // 1、创建链接
        ZkClient zkClient = new ZkClient(ZK_HOST);
        // ZkClient zkClient = new ZkClient(new ZkConnection(ZK_HOST), 5000);
        // 2、创建节点
        //zkClient.create("/zk", "test", CreateMode.PERSISTENT);
        //zkClient.createPersistent("/zkclient/test", true);

        // 修改节点内容
        // zkClient.writeData("/zkclient/test", "modify data");

        // 3、删除节点
        //zkClient.delete("/zk");
        // 递归删除
        //zkClient.deleteRecursive("/zkclient/test");

        //List<String> childrens = zkClient.getChildren("/test");
        //log.info("childrens: {}", childrens);
        zkClient.subscribeChildChanges("/test", new IZkChildListener() {
            @Override
            public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
                log.info("parent node: {}", parentPath);
                log.info("current childs: {}", currentChilds);
            }
        });

        Thread.sleep(3000);

        zkClient.createPersistent("/test/a");
        Thread.sleep(1000);

        zkClient.deleteRecursive("/test");

        Thread.sleep(Integer.MAX_VALUE);

    }
}

实现通知:

package com.cc.springbootzookeeperclient;

import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.*;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * Created by CarlosXiao on 2018/7/28.
 */
@Slf4j
public class ZookeeperTest implements Watcher{

    public static final String ZK_HOST = "192.168.13.51:2182,192.168.13.51:2183,192.168.13.51:2184,192.168.13.51:2185";


    private static CountDownLatch countDownLatch = new CountDownLatch(1);

    public static void main(String [] args) throws IOException, InterruptedException, KeeperException {
        // 1、 创建会话,
        /**
         * 1、 链接字符串 192.168.13.51:2182,192.168.13.51:2183
         */
        ZooKeeper zooKeeper = new ZooKeeper(ZK_HOST, 5000, new ZookeeperTest());

        countDownLatch.await();

        // 2. 创建节点
        zooKeeper.create("/test", "aaa".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

        // 3. 设置节点内容
        zooKeeper.setData("/test", "bbb".getBytes(), -1);

        zooKeeper.create("/test/1", "aaa".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        zooKeeper.create("/test/2", "aaa".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        zooKeeper.create("/test/3", "aaa".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        zooKeeper.create("/test/4", "aaa".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        // 5. 获取子节点
        List<String> childrens = zooKeeper.getChildren("/test", false);
        log.info("childrens: {}", childrens);

        // 4. 节点删除
        zooKeeper.delete("/test", -1);

        Thread.sleep(Integer.MAX_VALUE);

    }

    @Override
    public void process(WatchedEvent event) {
        if (event.getState() == Event.KeeperState.SyncConnected) {
            log.info("--------------------------> 已连接");
            countDownLatch.countDown();
        }
    }
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
可以通过以下步骤来解决Spring Boot连接不上Zookeeper的问题: 1. 确保在pom.xml文件中添加了正确的Zookeeper依赖项。请检查以下代码片段是否存在于pom.xml文件中: ```xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.12</version> </dependency> </dependencies> ``` 2. 确保已正确下载并安装了Zookeeper。您可以从Apache官方网站下载Zookeeper二进制文件。请确保下载的版本与pom.xml文件中指定的版本一致。 3. 确保Zookeeper已正确运行。在Windows 10上,您可以按照以下步骤运行Zookeeper: - 解压下载的Zookeeper二进制文件。 - 在解压后的目录中,找到并重命名`zoo_sample.cfg`文件为`zoo.cfg`。 - 打开命令提示符,并导航到Zookeeper的bin目录。 - 运行以下命令启动Zookeeper服务器: ```shell .\zkServer.cmd ``` 4. 检查Spring Boot应用程序的配置文件,确保已正确配置Zookeeper连接参数。您可以在`application.properties`或`application.yml`文件中添加以下配置: ```properties spring.cloud.zookeeper.connect-string=localhost:2181 ``` 5. 检查防火墙设置,确保Zookeeper的端口(默认为2181)未被阻止。 如果您按照上述步骤操作仍然无法连接Zookeeper,请检查网络连接Zookeeper服务器的状态,并确保您的代码没有其他问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

择业

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值