ZooKeeper之Java客户端API使用—检测节点是否存在
客户端可以通过ZooKeeper的API来检测节点是否存在,有如下4个接口:
- public Stat exists(final String path, Watcher watcher)
- public Stat exists(String path, boolean watch)
- public void exists(final String path, Watcher watcher, StatCallback cb, Object ctx)
- public void exists(String path, boolean watch, StatCallback cb, Object ctx)
这里列出的4个API分别是用同步和异步方式来检测节点是否存在的接口,API方法的参数说明如下表所示。
参数名 说明 path 指定数据节的节点路径,即API调用的目的是检测该节点是否存在 watcher 注册的Watcher,用于监听以下三类事件:
- 节点被创建
- 节点被删除
- 节点被更新
watch 指定是否复用ZooKeeper中默认的Watcher cb 注册一个异步回调函数 ctx 用于传递上下文信息的对象
该接口主要用于检测指定节点是否存在,返回值是一个stat对象。另外,如果在调用接口时注册Watcher的话,还可以对节点是否存在进行监听——一旦节点被创建、被删除或是数据被更新,都会通知客户端。
使用同步API检测节点是否存在
// ZooKeeper API 检测节点是否存在,使用同步(sync)接口
public class Exist_API_Sync_Usage implements Watcher {
private static CountDownLatch connectedSemaphore = new CountDownLatch(1);
private static ZooKeeper zk;
public static void main(String[] args) throws Exception {
String path = “/zk-book”;
zk = new ZooKeeper(“domain1.book.zookeeper:2181”, 5000, new Exist_API_Sync_Usage());
connectedSemaphore.await();
zk.exists(path, true);
zk.create(path, “”.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zk.setData(path, “123”.getBytes(), -1);
zk.create(path+”/c1”, “”.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zk.delete(path+”/c1”, -1);
zk.delete(path, -1);
Thread.sleep(Integer.MAX_VALUE);
}
@Override
public void process(WatchedEvent event) {
try {
if(KeeprState.SyncConnected == event.getState()) {
if(EventType.None == event.getType() && null == event.getPath()) {
connectedSemaphore.countDown();
} else if (EventType.NodeCreated == event.getType()) {
System.out.println(“Node(“ + event.getPath() + “)Created”);
zk.exists(event.getPath(), true);
} else if (EventType.NodeDeleted == event.getType()) {
System.out.println(“Node(“ + event.getPath() + “)Deleted”);
zk.exists(event.getPath(), true);
} else if (EventType.NodeDataChanged == event.getType()) {
System.out.println(“Node(“ + event.getPath() + “)DataChanged”);
zk.exists(event.getPath(), true);
}
}
} catch(Exception e) {}
}
}
运行程序,输出结果如下:
在上面的示例程序中,针对节点/zk-book(初始状态,服务器上是不存在该节点的),我们先后进行了如下操作。
- 通过exists接口来检测是否存在指定节点,同时注册了一个Watcher。
- 创建节点/zk-book,此时服务端马上会向客户端发送一个事件通知:NodeCreated。客户端在收到该事件通知后,再次调用exists接口,同时注册Watcher。
- 更新该节点的数据,这个时候,服务端又会向客户端发送一个事件通知:NodeDataChanged。客户端在收到该事件通知后,继续调用exists接口,同时注册Watcher。
- 创建子节点/zk-book/c1。
- 删除子节点/zk-book/c2。
- 删除节点/zk-book。此时客户端会收到服务端的事件通知:NodeDeleted。
从上面6个操作步骤以及服务端对应的通知发送中,我们可以得出如下结论。
- 无论指定节点是否存在,通过调用exists接口都可以注册Watcher。
- exists接口中注册的Watcher,能够对节点创建、节点删除和节点数据更新事件进行监听。
- 对于指定节点的子节点的各种变化,都不会通知客户端。
还没有评论,来说两句吧...