ZkClient是由Datameer的工程师开发的开源客户端,对Zookeeper的原生API进行了包装,实现了超时重连、Watcher反复注册等功能。
在使用ZooKeeper的Java客户端时,经常需要处理几个问题:重复注册watcher、session失效重连、异常处理。
    目前已经运用到了很多项目中,知名的有Dubbo、Kafka、Helix。

增加依赖

<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>

创建连接

public class SessionDemo {

private static final String ZKSERVERS = "113.140.81.67:18081";

public static void main(String[] args) {
ZkClient zkClient = new ZkClient(ZKSERVERS);
System.out.println(zkClient + "--->success");
}
}

基本操作

创建节点

//提供递归创建父类
zkClient.createPersistent("/zkclient/zkclient1/zkclient1-1/zkclient1-1-1",true);
System.out.println("success");
zkClient.createPersistent("/zkclient",true);
//这个方法得确保父节点都存在不然直接抛异常
zkClient.createPersistent("/zkclient/zkclient1/zkclient1-1/zkclient1-1-1/dd","ddd");

源码分析:

public void createPersistent(String path, boolean createParents, List<ACL> acl) throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
try {
create(path, null, acl, CreateMode.PERSISTENT);
} catch (ZkNodeExistsException e) {
if (!createParents) {
throw e;
}
} catch (ZkNoNodeException e) {
if (!createParents) {
throw e;
}
String parentDir = path.substring(0, path.lastIndexOf('/'));
createPersistent(parentDir, createParents, acl);
createPersistent(path, createParents, acl);
}
}

上面是递归创建父类的核心源码:
create创建多级节点会抛出异常ZkNoNodeException ,这样/zkclient/zkclient1/zkclient1-1/zkclient1-1-1是不存在的一定抛异常,进入catch,第一次parentDir 将变成了/zkclient/zkclient1/zkclient1-1再次递归调用createPersistent,同样是不存在的这样递归直到parentDir=zkclient时不会抛出异常,/zkclient创建成功后会再次调用下面的 createPersistent(path, createParents, acl);进行一级一级的创建直到把/zkclient/zkclient1/zkclient1-1/zkclient1-1-1完整创建

其他操作

其他操作比较简单不再赘述

public static void main(String[] args) {
ZkClient zkClient = getInstance();
//提供递归创建父类
zkClient.createPersistent("/zkclient2/zkclient1/zkclient1-1/zkclient1-1-1/dd",true);
System.out.println("success");
zkClient.createPersistent("/zkclient",true);
//这个方法得确保父节点都存在不然直接抛异常
//zkClient.createPersistent("/zkclient/zkclient1/zkclient1-1/zkclient1-1-1/dd","ddd");

//判断是否存在
boolean exists = zkClient.exists("/zkclient/zkclient1/zkclient1-1/zkclient1-1-1/dd");
System.out.println(exists);

if (exists){
zkClient.writeData("/zkclient/zkclient1/zkclient1-1/zkclient1-1-1/dd","我修改了");
Object readData = zkClient.readData("/zkclient/zkclient1/zkclient1-1/zkclient1-1-1/dd");
System.out.println(readData.toString());
boolean delete = zkClient.delete("/zkclient/zkclient1/zkclient1-1/zkclient1-1-1/dd");
System.out.println("删除成功"+delete);
}
}