前面一篇介绍了使用zk原生api链接zk集群进行基本api的演示,演示了连接zk初始化的过程和创建节点的过程。本篇演示获取子节点,获取数据的同步异步获取代码demo.
package com.coderman.zookeeper.clusterdemo.version2;
import com.alibaba.fastjson.JSON;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
/**
* @description:
* @author: Fanchunshuai
* @time: 2020/2/10 17:14
*/
public class GetChildrenAPIDemo implements Watcher {
private static StringBuffer buffer = new StringBuffer();
private static CountDownLatch countDownLatch = new CountDownLatch(1);
private static final int SESSION_TIMEOUT = 5000;
protected static ZooKeeper zooKeeper;
private static Stat stat = new Stat();
static {
buffer.append("192.168.1.224:2184,");
buffer.append("192.168.1.224:2181,");
buffer.append("192.168.1.224:2182,");
buffer.append("192.168.1.224:2183,");
buffer.append("192.168.1.224:2185");
}
public static void main(String[] args) throws InterruptedException, IOException, KeeperException {
//getChildrenSync();
//getChildrenASync();
getDataAPI();
}
/**
* 同步获取子节点
* @throws IOException
* @throws InterruptedException
* @throws KeeperException
*/
private static void getChildrenSync() throws IOException, InterruptedException, KeeperException {
String path = "/zk-demo2";
zooKeeper = new ZooKeeper(buffer.toString(),SESSION_TIMEOUT,new GetChildrenAPIDemo());
countDownLatch.await();
//同步创建一个持久节点
zooKeeper.create(path,"".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//同步创建一个临时子节点
zooKeeper.create(path+"/children1","".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
//获取子节点的时候,通过第二个参数注册监听器
List<String> nodes = zooKeeper.getChildren(path,true);
System.out.println(JSON.toJSONString(nodes));
//重新创建子节点
zooKeeper.create(path+"/children2","".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
Thread.sleep(1000000L);
}
/**
* 异步获取子节点
* 异步接口通常应用在这样的使用场景中:应用启动的时候,
* 会获取一些配置信息,例如机器配置表等,这些配置通常比较大,并且不希望
* 配置的获取影响应用的主流程。
* @throws IOException
* @throws InterruptedException
* @throws KeeperException
*/
private static void getChildrenASync() throws IOException, InterruptedException, KeeperException {
String path = "/zk-demo3";
zooKeeper = new ZooKeeper(buffer.toString(),SESSION_TIMEOUT,new GetChildrenAPIDemo());
countDownLatch.await();
//同步创建一个持久节点
zooKeeper.create(path,"".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//同步创建一个临时子节点
zooKeeper.create(path+"/children1","".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
//获取子节点的时候,通过第二个参数注册自定义监听器
zooKeeper.getChildren(path,true,new IChildren2Callback(),null);
//重新创建子节点
zooKeeper.create(path+"/children2","".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
Thread.sleep(1000000L);
}
/**
*
* getData Api
* 返回的数据是byte[]类型
* @throws IOException
* @throws InterruptedException
* @throws KeeperException
*/
private static void getDataAPI() throws IOException, InterruptedException, KeeperException {
String path = "/zk-demo4";
zooKeeper = new ZooKeeper(buffer.toString(),SESSION_TIMEOUT,new GetChildrenAPIDemo());
countDownLatch.await();
zooKeeper.create(path,"123456".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
//这里是同步调用,也可以有异步调用,异步调用的回调函数使用DataCallBack接口作为回调函数
String data = new String(zooKeeper.getData(path,true,stat));
System.out.println(stat.getCzxid()+","+stat.getMzxid());
zooKeeper.setData(path,"1212".getBytes(),-1);
//异步调用获取数据
zooKeeper.getData(path, true, new IDataCallBack(),null);
Thread.sleep(Integer.MAX_VALUE);
}
@Override
public void process(WatchedEvent watchedEvent) {
if(Event.KeeperState.SyncConnected == watchedEvent.getState()){
if(Event.EventType.None == watchedEvent.getType() && null == watchedEvent.getPath()){
countDownLatch.countDown();
}
//子节点变更监听
//这里需要说明的是zk服务器在向客户端发送Watcher
//"NodeChildrenChanaged"事件通知的时候,仅仅只会
//发出一个通知,而不会把节点变化的情况发送给客户端,需要客户端自己
//重新获取。另外Watcher通知是一次性的,触发通知之后
//就失效了,因此客户端需要重复注册Watcher
else if(Event.EventType.NodeChildrenChanged == watchedEvent.getType()){
try {
System.out.println("reget the changed child node = "+zooKeeper.getChildren(watchedEvent.getPath(),true));
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//监听节点数据变化
else if(Event.EventType.NodeDataChanged == watchedEvent.getType()){
try {
System.out.println(new String(zooKeeper.getData(watchedEvent.getPath(),true,stat)));
System.out.println(stat.getCzxid()+","+stat.getMzxid()+","+stat.getVersion());
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 自定义回调函数
*/
static class IChildren2Callback implements AsyncCallback.Children2Callback{
@Override
public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) {
System.out.println("Get children znode result = [response code : "+rc+",path = "+path+",ctx = "+ctx
+",stat = "+stat);
}
}
/**
* 数据类型的回调函数
*/
static class IDataCallBack implements AsyncCallback.DataCallback{
@Override
public void processResult(int i, String s, Object o, byte[] bytes, Stat stat) {
System.out.println("rc = "+i+",path = "+s+",data = "+new String(bytes));
System.out.println(stat.getCzxid()+","+stat.getMzxid()+","+stat.getVersion());
}
}
}