乐趣区

关于java:实战ZooKeeper-实战

1. 前言

这篇文章简略给演示一下 ZooKeeper 常见命令的应用以及 ZooKeeper Java 客户端 Curator 的根本应用。介绍到的内容都是最根本的操作,能满足日常工作的根本须要。

如果文章有任何须要改善和欠缺的中央,欢送在评论区指出,共同进步!

2. ZooKeeper 装置和应用

2.1. 应用 Docker 装置 zookeeper

a. 应用 Docker 下载 ZooKeeper

docker pull zookeeper:3.5.8

b. 运行 ZooKeeper

docker run -d --name zookeeper -p 2181:2181 zookeeper:3.5.8

2.2. 连贯 ZooKeeper 服务

a. 进入 ZooKeeper 容器中

先应用 docker ps 查看 ZooKeeper 的 ContainerID,而后应用 docker exec -it ContainerID /bin/bash 命令进入容器中。

b. 先进入 bin 目录, 而后通过 ./zkCli.sh -server 127.0.0.1:2181命令连贯 ZooKeeper 服务

root@eaf70fc620cb:/apache-zookeeper-3.5.8-bin# cd bin

如果你看到控制台胜利打印出如下信息的话,阐明你曾经胜利连贯 ZooKeeper 服务。

2.3. 常用命令演示

2.3.1. 查看常用命令(help 命令)

通过 help 命令查看 ZooKeeper 常用命令

2.3.2. 创立节点(create 命令)

通过 create 命令在根目录创立了 node1 节点,与它关联的字符串是 ”node1″

[zk: 127.0.0.1:2181(CONNECTED) 34] create /node1“node1”

通过 create 命令在根目录创立了 node1 节点,与它关联的内容是数字 123

[zk: 127.0.0.1:2181(CONNECTED) 1] create /node1/node1.1 123
Created /node1/node1.1

2.3.3. 更新节点数据内容(set 命令)

[zk: 127.0.0.1:2181(CONNECTED) 11] set /node1 "set node1"

2.3.4. 获取节点的数据(get 命令)

get 命令能够获取指定节点的数据内容和节点的状态, 能够看出咱们通过 set 命令曾经将节点数据内容改为 “set node1″。

set node1
cZxid = 0x47
ctime = Sun Jan 20 10:22:59 CST 2019
mZxid = 0x4b
mtime = Sun Jan 20 10:41:10 CST 2019
pZxid = 0x4a
cversion = 1
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 9
numChildren = 1

2.3.5. 查看某个目录下的子节点(ls 命令)

通过 ls 命令查看根目录下的节点

[zk: 127.0.0.1:2181(CONNECTED) 37] ls /
[dubbo, ZooKeeper, node1]

通过 ls 命令查看 node1 目录下的节点

[zk: 127.0.0.1:2181(CONNECTED) 5] ls /node1
[node1.1]

ZooKeeper 中的 ls 命令和 linux 命令中的 ls 相似,这个命令将列出绝对路径 path 下的所有子节点信息(列出 1 级,并不递归)

2.3.6. 查看节点状态(stat 命令)

通过 stat 命令查看节点状态

[zk: 127.0.0.1:2181(CONNECTED) 10] stat /node1
cZxid = 0x47
ctime = Sun Jan 20 10:22:59 CST 2019
mZxid = 0x47
mtime = Sun Jan 20 10:22:59 CST 2019
pZxid = 0x4a
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 11
numChildren = 1

下面显示的一些信息比方 cversion、aclVersion、numChildren 等等,我在下面“znode(数据节点)的构造”这部分曾经介绍到。

2.3.7. 查看节点信息和状态(ls2 命令)

ls2 命令更像是 ls 命令和 stat 命令的联合。ls2 命令返回的信息包含 2 局部:

  1. 子节点列表
  2. 以后节点的 stat 信息。
[zk: 127.0.0.1:2181(CONNECTED) 7] ls2 /node1
[node1.1]
cZxid = 0x47
ctime = Sun Jan 20 10:22:59 CST 2019
mZxid = 0x47
mtime = Sun Jan 20 10:22:59 CST 2019
pZxid = 0x4a
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 11
numChildren = 1

2.3.8. 删除节点(delete 命令)

这个命令很简略,然而须要留神的一点是如果你要删除某一个节点,那么这个节点必须无子节点才行。

[zk: 127.0.0.1:2181(CONNECTED) 3] delete /node1/node1.1

在前面我会介绍到 Java 客户端 API 的应用以及开源 ZooKeeper 客户端 ZkClient 和 Curator 的应用。

3. ZooKeeper Java 客户端 Curator 简略应用

Curator 是 Netflix 公司开源的一套 ZooKeeper Java 客户端框架,相比于 Zookeeper 自带的客户端 zookeeper 来说,Curator 的封装更加欠缺,各种 API 都能够比拟不便地应用。

上面咱们就来简略地演示一下 Curator 的应用吧!

Curator4.0+ 版本对 ZooKeeper 3.5.x 反对比拟好。开始之前,请先将上面的依赖增加进你的我的项目。

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>4.2.0</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>4.2.0</version>
</dependency>

3.1. 连贯 ZooKeeper 客户端

通过 CuratorFrameworkFactory 创立 CuratorFramework 对象,而后再调用 CuratorFramework 对象的 start() 办法即可!

private static final int BASE_SLEEP_TIME = 1000;
private static final int MAX_RETRIES = 3;

// Retry strategy. Retry 3 times, and will increase the sleep time between retries.
RetryPolicy retryPolicy = new ExponentialBackoffRetry(BASE_SLEEP_TIME, MAX_RETRIES);
CuratorFramework zkClient = CuratorFrameworkFactory.builder()
    // the server to connect to (can be a server list)
    .connectString("127.0.0.1:2181")
    .retryPolicy(retryPolicy)
    .build();
zkClient.start();

对于一些基本参数的阐明:

  • baseSleepTimeMs:重试之间期待的初始工夫
  • maxRetries:最大重试次数
  • connectString:要连贯的服务器列表
  • retryPolicy:重试策略

3.2. 数据节点的增删改查

3.2.1. 创立节点

咱们在 ZooKeeper 常见概念解读 中介绍到,咱们通常是将 znode 分为 4 大类:

  • 长久(PERSISTENT)节点:一旦创立就始终存在即便 ZooKeeper 集群宕机,直到将其删除。
  • 长期(EPHEMERAL)节点 :长期节点的生命周期是与  客户端会话(session) 绑定的,会话隐没则节点隐没 。并且,长期节点  只能做叶子节点,不能创立子节点。
  • 长久程序(PERSISTENT_SEQUENTIAL)节点:除了具备长久(PERSISTENT)节点的个性之外,子节点的名称还具备程序性。比方 /node1/app0000000001/node1/app0000000002
  • 长期程序(EPHEMERAL_SEQUENTIAL)节点:除了具备长期(EPHEMERAL)节点的个性之外,子节点的名称还具备程序性。

你在应用的 ZooKeeper 的时候,会发现 CreateMode 类中理论有 7 种 znode 类型,然而用的最多的还是下面介绍的 4 种。

a. 创立长久化节点

你能够通过上面两种形式创立长久化的节点。

// 留神: 上面的代码会报错,下文说了具体起因
zkClient.create().forPath("/node1/00001");
zkClient.create().withMode(CreateMode.PERSISTENT).forPath("/node1/00002");

然而,你运行下面的代码会报错,这是因为的父节点 node1 还未创立。

你能够先创立父节点 node1,而后再执行下面的代码就不会报错了。

zkClient.create().forPath("/node1");

更举荐的形式是通过上面这行代码,creatingParentsIfNeeded() 能够保障父节点不存在的时候主动创立父节点,这是十分有用的。

zkClient.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/node1/00001");

b. 创立长期节点

zkClient.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath("/node1/00001");

c. 创立节点并指定数据内容

zkClient.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath("/node1/00001","java".getBytes());
zkClient.getData().forPath("/node1/00001");// 获取节点的数据内容,获取到的是 byte 数组

d. 检测节点是否创立胜利

zkClient.checkExists().forPath("/node1/00001");// 不为 null 的话,阐明节点创立胜利

3.2.2. 删除节点

a. 删除一个子节点

zkClient.delete().forPath("/node1/00001");

b. 删除一个节点以及其下的所有子节点

zkClient.delete().deletingChildrenIfNeeded().forPath("/node1");

3.2.3. 获取 / 更新节点数据内容

zkClient.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath("/node1/00001","java".getBytes());
zkClient.getData().forPath("/node1/00001");// 获取节点的数据内容
zkClient.setData().forPath("/node1/00001","c++".getBytes());// 更新节点数据内容

3.2.4. 获取某个节点的所有子节点门路

List<String> childrenPaths = zkClient.getChildren().forPath("/node1");
退出移动版