这里介绍其他的API对zookeeper的操作。
- 同步方式获取子节点数据
public static void getChildrenSync() throws KeeperException, InterruptedException { List<String> childrenList = zkClient().getChildren("/", true); for(String child:childrenList){ System.out.println(child); } }
方法getChildren的第二个参数同样为watch,当节点的子节点列表发生变化时,zk服务器会向我们推送类型为NodeChildrenChanged的事件。
- 异步方式获取子节点数据
public static void main(String[] args) throws Exception {
ZooKeeper zooKeeper = new ZooKeeper("127.0.0.1:2182", 5000, new CreateNode());
countDownLatch.await();
zooKeeper.getChildren("/",true,new MyStringCallBackList(),"获取/下面的子节点");
Thread.sleep(10000);
}
static class MyStringCallBackList implements AsyncCallback.Children2Callback{
@Override
public void processResult(
final int rc, final String path, final Object ctx,
final List<String> children, final Stat stat) {
System.out.println(rc);
System.out.println(path);
System.out.println(ctx);
for(String child : children) {
System.out.println(child);
}
System.out.println(stat);
}
}
- 查看一个节点是否存在(同步)
/**
* 同步的方式查看一个节点是否存在
* @throws KeeperException
* @throws InterruptedException
*/
public static void existSync() throws KeeperException, InterruptedException {
Stat stat = zkClient().exists("/poype_node2", true);
if(stat!=null){
System.out.println("节点存在"+stat);
}
}
exists方法的watch参数比较特别,如果将其指定为true,那么代表你对该节点的创建事件、节点删除事件和该节点的数据内容改变事件都感兴趣,所以会同时响应三种事件类型。请看process方法中对事件的处理:
public void process(WatchedEvent watchedEvent) {
if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
if(watchedEvent.getType() == Event.EventType.None && null == watchedEvent.getPath()) {
existAsync();
} else if(watchedEvent.getType() == Event.EventType.NodeCreated) {
System.out.println("监控到了该节点被创建");
existAsync();
} else if(watchedEvent.getType() == Event.EventType.NodeDataChanged) {
System.out.println("监控到了该节点的数据内容发生变化");
existAsync();
} else if(watchedEvent.getType() == Event.EventType.NodeDeleted) {
System.out.println("监控到了该节点被删除");
existAsync();
}
}
}
- 查看一个节点是否存在(异步)
private static void existAsync() throws IOException {
getZKClient().exists("/poype_node2", true, new AsyncCallback.StatCallback() {
@Override
public void processResult(int resultCode, String path, Object ctx, Stat stat) {
System.out.println(resultCode);
System.out.println(path);
System.out.println(ctx);
System.out.println(stat);
}
}, "异步查看一个节点是否存在");
}
public static ZooKeeper getZKClient() throws IOException {
return new ZooKeeper("127.0.0.1:2182", 5000, new CreateNode());
}
- 修改节点数据(同步)
public static void setDataSync() throws KeeperException, InterruptedException {
Stat stat = zkClient().setData("/poype_node2", "9888328".getBytes(), 1);
System.out.println(stat);
}
setData方法有三个参数,前两个参数分别是节点的路径和要修改的数据值,最后一个参数是version字段。在调用setData方法修改节点数据内容时,只有当version参数的值与节点状态信息中的dataVersion值相等时,数据修改才能成功,否则会抛出BadVersion异常。这是为了防止丢失数据的更新,在ZooKeeper提供的API中,所有的写操作(例如后面要提到的delete)都有version参数。
- 异步修改节点的数据内容:
public static ZooKeeper getZKClient() throws IOException {
return new ZooKeeper("127.0.0.1:2182", 5000, new CreateNode());
}
public static void setDataAsync() throws IOException {
getZKClient().setData("/poype_node2", "poype5211314".getBytes(), 3, new AsyncCallback.StatCallback() {
@Override
public void processResult(int resultCode, String path, Object ctx, Stat stat) {
System.out.println(resultCode);
System.out.println(path);
System.out.println(ctx);
System.out.println(stat.getVersion());
}
}, "异步设置一个节点的数据");
}
-
删除一个节点(同步)
public static void deleteSync() throws KeeperException, InterruptedException {
zkClient().delete("/poype_node2",0);
}
- 删除一个节点(异步)
-
private void deleteAsync() { zooKeeper.delete("/poype_node", 3, new AsyncCallback.VoidCallback() { public void processResult(int resultCode, String path, Object ctx) { System.out.println(resultCode); System.out.println(path); System.out.println(ctx); } }, "异步删除一个节点"); }