Zookeeper之开源客户端ZkClient

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: Zookeeper之开源客户端ZkClient

ZkClient是由Datameer的工程师开发的开源客户端,对Zookeeper的原生API进行了包装,实现了超时重连、Watcher反复注册等功能。


ZKClient版本及源码

maven依赖

ZkClient目前有两个不同artifactId的系列。

其中最早的0.1版本maven依赖如下:


<dependency>
     <groupId>org.apache.zookeeper</groupId>
     <artifactId>zookeeper</artifactId>
     <version>3.4.9</version>
 </dependency>
 <dependency>
     <groupId>com.github.sgroschupf</groupId>
     <artifactId>zkclient</artifactId>
     <version>0.1</version>
 </dependency>

另外一个系列为的maven依赖为:

<dependency>
     <groupId>org.apache.zookeeper</groupId>
     <artifactId>zookeeper</artifactId>
     <version>3.4.9</version>
 </dependency>
<dependency>
    <groupId>com.101tec</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.10</version>
</dependency>

其中第二个系列包含了从0.1~0.10的版本。查看dubbo的源代码,我们可以看到,dubbo采用了第一个系列的0.1版本。


源代码

github源代码地址:https://github.com/sgroschupf/zkclient


ZkClient使用

以下我们以第二个系列的0.10版本为例来说明ZKClient的API和使用


创建会话

ZkClient提供了7中创建会话的方法:


public ZkClient(String serverstring)
public ZkClient(String zkServers, int connectionTimeout)
public ZkClient(String zkServers, int sessionTimeout, int connectionTimeout)
public ZkClient(String zkServers, int sessionTimeout, int connectionTimeout, ZkSerializer zkSerializer)
public ZkClient(final String zkServers, final int sessionTimeout, final int connectionTimeout, final ZkSerializer zkSerializer, final long operationRetryTimeout)
public ZkClient(IZkConnection connection)
public ZkClient(IZkConnection connection, int connectionTimeout)
public ZkClient(IZkConnection zkConnection, int connectionTimeout, ZkSerializer zkSerializer)
public ZkClient(final IZkConnection zkConnection, final int connectionTimeout, final ZkSerializer zkSerializer, final long operationRetryTimeout)

上面方法的参数如果我们熟悉原生API的话,不难理解其参数,基本上参数名都是自描述的。值得留意的是ZkClient将ZK原生API中的异步处理进行了同步化。


其中一个参数IZkConnection是一个接口的定义。查看接口的方法不难发现它是对ZK原生接口最直接的包装。在此接口下面有两个实现方法ZkConnection和InMemoryConnection。在日常中直接使用ZkConnection方法就可以解决大部分的常见业务需求。


参数ZkSerializer同样是一个接口,定义了byte数组序列化和反序列化的两个方法。如果不传递此参数,则默认使用org.I0Itec.zkclient.serialize.SerializableSerializer实现类进行序列化。某些情况下此序列化接口会出现问题,比如乱码。此时,开发者可以直接实现ZkSerializer接口,重写自己的序列化方法。比如使用Hessian或Kryo等。


通观上面9个创建会话的构造方法,我们发现已经没有Watcher的存在了。同时,ZkClient通过Listener来实现Wather注册,从API级别来支持Watcher监听的注册。


package com.secbro.learn.zkclient;
import org.I0Itec.zkclient.ZkClient;
/**
 * Created by zhuzs on 2017/3/31.
 */
public class TestZkClient {
    public static void main(String[] args) {
        ZkClient zkClient = new ZkClient("127.0.0.1:2181",5000);
        System.out.println("ZK 成功建立连接!");
    }
}

创建节点

ZkClient提供了15个创建节点的方法:

public void createPersistent(String path)
public void createPersistent(String path, boolean createParents)
public void createPersistent(String path, boolean createParents, List<ACL> acl)
public void createPersistent(String path, Object data)
public void createPersistent(String path, Object data, List<ACL> acl)
public String createPersistentSequential(String path, Object data)
public String createPersistentSequential(String path, Object data, List<ACL> acl) 
public void createEphemeral(final String path)
public void createEphemeral(final String path, final List<ACL> acl)
public String create(final String path, Object data, final CreateMode mode)
public String create(final String path, Object data, final List<ACL> acl, final CreateMode mode) 
public void createEphemeral(final String path, final Object data)
public void createEphemeral(final String path, final Object data, final List<ACL> acl)
public String createEphemeralSequential(final String path, final Object data)
public String createEphemeralSequential(final String path, final Object data, final List<ACL> acl)

查看源代码可知,其实这些创建节点的方法都是对原生API的一层封装而已,底层实现基本相同。值得留意的一点是,原生API的参数通过byte[]来传递节点内容,而ZkClient支持自定义序列化,因此可以传输Object对象。


createParents参数决定了是否递归创建父节点。true表示递归创建,false表示不使用递归创建。这也正是ZkClient帮开发人员省去了不少繁琐的检查和创建父节点的过程。


删除节点

删除节点提供了以下方法:


public boolean delete(final String path)


public boolean delete(final String path, final int version)


public boolean deleteRecursive(String path)

删除API其实很简单,重点说一下deleteRecursive接口,这个接口提供了递归删除的功能。在原生API中,如果一个节点存在子节点,那么它将无法直接删除,必须一层层遍历先删除全部子节点,然后才能将目标节点删除。


读取节点

获取节点列表

public List<String> getChildren(String path)

1

此接口返回子节点的相对路径列表。比如节点路径为/test/a1和/test/a2,那么当path为/test时,返回的结果为[a1,a2]。


其中在原始API中,对节点注册Watcher,当节点被删除或其下面的子节点新增或删除时,会通知客户端。在ZkClient中,通过Listener监听来实现,后续会将到具体的使用方法。


可以注册的Listener为,接口IZkChildListener下面的方法来实现:


public void handleChildChange(String parentPath, List<String> currentChilds)

1

获取节点内容

public <T extends Object> T readData(String path)


public <T extends Object> T readData(String path, boolean returnNullIfPathNotExists)


public <T extends Object> T readData(String path, Stat stat)


通过方法返回参数的定义,就可以得知,返回的结果(节点的内容)已经被反序列化成对象了。


对本接口实现监听的接口为IZkDataListener,分别提供了处理数据变化和删除操作的监听:


public void handleDataChange(String dataPath, Object data) throws Exception;


public void handleDataDeleted(String dataPath) throws Exception;


更新数据

更新操作可以通过以下接口来实现:


public void writeData(String path, Object object)


public void writeData(final String path, Object datat, final int expectedVersion)


public Stat writeDataReturnStat(final String path, Object datat, final int expectedVersion)


监测节点是否存在

此API比较简单,调用以下方法即可:


protected boolean exists(final String path, final boolean watch)

1

注册监听

在ZkClient中客户端可以通过注册相关的事件监听来实现对Zookeeper服务端时间的订阅。其中ZkClient提供的监听事件接口有以下几种:


接口类 注册监听方法 解除监听方法

IZkChildListener ZkClient的subscribeChildChanges方法 ZkClient的unsubscribeChildChanges方法

IZkDataListener ZkClient的subscribeDataChanges方法 ZkClient的subscribeChildChanges方法

IZkStateListener ZkClient的subscribeStateChanges方法 ZkClient的unsubscribeStateChanges方法

其中ZkClient还提供了一个unsubscribeAll方法,来解除所有监听。


下面以IZkChildListener为例来举例说明使用方法:

package com.secbro.learn.zkclient;
import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.ZkClient;
import java.util.List;
/**
 * Created by zhuzs on 2017/3/31.
 */
public class TestZkClient {
    public static void main(String[] args) throws InterruptedException {
        ZkClient zkClient = new ZkClient("127.0.0.1:2181",5000);
        System.out.println("ZK 成功建立连接!");
        String path = "/zk-test";
        // 注册子节点变更监听(此时path节点并不存在,但可以进行监听注册)
        zkClient.subscribeChildChanges(path, new IZkChildListener() {
            public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
                System.out.println("路径" + parentPath +"下面的子节点变更。子节点为:" + currentChilds );
            }
        });
        // 递归创建子节点(此时父节点并不存在)
        zkClient.createPersistent("/zk-test/a1",true);
        Thread.sleep(5000);
        System.out.println(zkClient.getChildren(path));
    }
}

执行结果为:

ZK 成功建立连接!
路径/zk-test下面的子节点变更。子节点为:[a1]
[a1]• 1
• 2
• 3

上面展示了Listener的基本使用方法,其他方法的使用读者可以自行尝试。

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
目录
相关文章
|
5天前
|
Java API Apache
ZooKeeper【基础 03】Java 客户端 Apache Curator 基础 API 使用举例(含源代码)
【4月更文挑战第11天】ZooKeeper【基础 03】Java 客户端 Apache Curator 基础 API 使用举例(含源代码)
23 11
|
13天前
|
存储
ZooKeeper客户端常用命令
ZooKeeper客户端常用命令
24 1
|
3月前
|
安全 Java API
Zookeeper(持续更新) VIP-02 Zookeeper客户端使用与集群特性
2,/usr/local/data/zookeeper-3,/usr/local/data/zookeeper-4,在每个目录中创建文件。创建四个文件夹/usr/local/data/zookeeper-1,/usr/local/data/zookeeper-Follower:只能处理读请求,同时作为 Leader的候选节点,即如果Leader宕机,Follower节点。己对外提供服务的起始状态。E: 角色, 默认是 participant,即参与过半机制的角色,选举,事务请求过半提交,还有一个是。
|
3月前
Zookeeper的客户端的命令
Zookeeper的客户端的命令
18 0
|
3月前
|
缓存 Java API
Zookeeper(持续更新) VIP-02 Zookeeper客户端使用与集群特性
Curator 是一套由netflix 公司开源的,Java 语言编程的 ZooKeeper 客户端框架,Curator项目是现在ZooKeeper 客户端中使用最多,对ZooKeeper 版本支持最好的第三方客户端,并推荐使用,Curator 把我们平时常用的很多 ZooKeeper 服务开发功能做了封装,例如 Leader 选举、分布式计数器、分布式锁。这就减少了技术人员在使用 ZooKeeper 时的大部分底层细节开发工作。
|
3月前
|
Apache
Apache ZooKeeper - 构建ZooKeeper源码环境及StandAlone模式下的服务端和客户端启动
Apache ZooKeeper - 构建ZooKeeper源码环境及StandAlone模式下的服务端和客户端启动
46 2
|
4月前
|
存储 设计模式 算法
深入浅出Zookeeper源码(六):客户端的请求在服务器中经历了什么
当我们向zk发出一个数据更新请求时,这个请求的处理流程是什么样的?zk又是使用了什么共识算法来保证一致性呢?带着这些问题,我们进入今天的正文。
137 1
深入浅出Zookeeper源码(六):客户端的请求在服务器中经历了什么
|
13天前
|
监控 负载均衡 Cloud Native
ZooKeeper分布式协调服务详解:面试经验与必备知识点解析
【4月更文挑战第9天】本文深入剖析ZooKeeper分布式协调服务原理,涵盖核心概念如Server、Client、ZNode、ACL、Watcher,以及ZAB协议在一致性、会话管理、Leader选举中的作用。讨论ZooKeeper数据模型、操作、会话管理、集群部署与管理、性能调优和监控。同时,文章探讨了ZooKeeper在分布式锁、队列、服务注册与发现等场景的应用,并在面试方面分析了与其它服务的区别、实战挑战及解决方案。附带Java客户端实现分布式锁的代码示例,助力提升面试表现。
30 2
|
3月前
|
消息中间件 Java 网络安全
JAVAEE分布式技术之Zookeeper的第一次课
JAVAEE分布式技术之Zookeeper的第一次课
70 0
|
1月前
|
监控 NoSQL Java
Zookeeper分布式锁
Zookeeper分布式锁
90 1