zookeeper 的客户端目前主要有三种,一种是原生的方式来操作来操作zookeeper(zookeeper实战04-Java操作zookeeper)、第二种采用开源的zkclient、第三种及本篇所讲的apache官方开源的Curator.
- Curator的优点
1、封装ZooKeeper client与ZooKeeper server之间的连接处理
2、提供了一套Fluent风格的操作API
3、提供ZooKeeper各种应用场景(recipe, 比如共享锁服务, 集群领导选举机制)的抽象封装
- 使用方式
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.0</version>
</dependency>
基本的curd的使用方式
- 增加节点
String nodePath = "/super/kkcl";
byte [] data = "kkcl".getBytes();
curatorOperator.client.create().creatingParentsIfNeeded()
.withMode(CreateMode.PERSISTENT)
.withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
.forPath(nodePath,data);
- 修改节点
byte [] newData = "newData".getBytes();
curatorOperator.client.setData().withVersion(0).forPath(nodePath,newData);
- 删除节点
curatorOperator.client.delete().guaranteed()
.deletingChildrenIfNeeded()
.withVersion(1)
.forPath(nodePath);
- 读取节点数据
Stat stat = new Stat();
byte [] da = curatorOperator.client.getData().storingStatIn(stat).forPath(nodePath);
System.out.println("节点:" + nodePath + "的数据为:" + new String(da));
System.out.println("该节点的版本号为:" + stat.getAversion());
- 查询子节点
List<String> childNodes = curatorOperator.client.getChildren().forPath(nodePath);
System.out.println("开始打印子节点");
for(String s : childNodes){
System.out.println(s);
- 判断节点是否存在
Stat stat = curatorOperator.client.checkExists().forPath(nodePath);
System.out.println(stat);
针对节点的监听
- 分为两种监听的方式:第一种使用一个类去实现watcher,并实现process方法;另一种方式是用一个类实现CuratorWatcher同时实现process方法。
curatorOperator.client.getData().usingWatcher(new MyCuratorWatcher()).forPath(nodePath);
curatorOperator.client.getData().usingWatcher(new MyWatcher()).forPath(nodePath);
完整的测试案列
public class CuratorOperator {
public CuratorFramework client = null;
public static final String path = "192.168.1.108:2182";
//实例化zookeeper客户端
public CuratorOperator(){
RetryPolicy retryPolicy = new RetryNTimes(3, 5000);
client = CuratorFrameworkFactory.builder()
.connectString(path)
.sessionTimeoutMs(50000).retryPolicy(retryPolicy)
//.build();
.namespace("workspace").build();
client.start();
}
//关闭zk客户端连接
public void closeZKClient(){
if(client != null){
this.client.close();
}
}
public static void main(String[] args) throws Exception {
CuratorOperator curatorOperator = new CuratorOperator();
boolean isZKCuratorStarted = curatorOperator.client.isStarted();
System.out.println("当前客户端的状态:" + (isZKCuratorStarted ? "连接中" : "已关闭"));
String nodePath = "/super/kkcl";
//创建节点
byte [] data = "kkcl".getBytes();
/**
curatorOperator.client.create().creatingParentsIfNeeded()
.withMode(CreateMode.PERSISTENT)
.withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
.forPath(nodePath,data);
*/
//更新节点数据
//byte [] newData = "newData".getBytes();
//curatorOperator.client.setData().withVersion(0).forPath(nodePath,newData);
//删除节点
/**
curatorOperator.client.delete().guaranteed()
.deletingChildrenIfNeeded()
.withVersion(1)
.forPath(nodePath);
*/
//读取节点的数据
/**
Stat stat = new Stat();
byte [] da = curatorOperator.client.getData().storingStatIn(stat).forPath(nodePath);
System.out.println("节点:" + nodePath + "的数据为:" + new String(da));
System.out.println("该节点的版本号为:" + stat.getAversion());
*/
//查询子节点
/**
List<String> childNodes = curatorOperator.client.getChildren().forPath(nodePath);
System.out.println("开始打印子节点");
for(String s : childNodes){
System.out.println(s);
}
*/
//判断节点是否存在
//Stat stat = curatorOperator.client.checkExists().forPath(nodePath);
//System.out.println(stat);
//watcher事件。当使用usingwatcher的时候,监听器只会触发一次,监听完毕就会销毁
//curatorOperator.client.getData().usingWatcher(new MyCuratorWatcher()).forPath(nodePath);
//curatorOperator.client.getData().usingWatcher(new MyWatcher()).forPath(nodePath);
Thread.sleep(3000);
curatorOperator.closeZKClient();
boolean isZKCuratorStarted02 = curatorOperator.client.isStarted();
System.out.println("当前客户端的状态:" + (isZKCuratorStarted02 ? "连接中" : "已关闭"));
}
}
来源:https://blog.csdn.net/qq_38061755/article/details/99694376