微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

zookeeper04-Java Api(2)事件监听

Watcher监听机制

在创建zookeeper会话时会传入一个Watcher,里面有两个特别关键的类:KeeperState(连接状态)和EventType(事件类型)。
如何拿到事件状态类型

//获取事件的状态
Event.KeeperState state = watchedEvent.getState(); //获取事件的状态
//获取事件的类型
Event.EventType type = watchedEvent.getType(); //获取事件的类型

KeeperState

KeeperState表示的是客户端与服务端连接的状态。

连接状态描述
disconnected客户端与服务器断开连接
SyncConnected客户端与服务器建立连接
AuthFailed客户端进行连接认证失败
ConnectedReadOnly客户端连接到的zookeeper服务是只读的
SaslAuthenticated用于通知客户端它们是SASL认证的
Expired客户端心跳检测没有收到服务端的响应时即认定断开连接,session失效

EventType

EventType表示的是节点发生变化时所触发的事件类型。

事件类型描述
NodeCreated被监听的节点被创建
nodechildrenChanged被监听的节点的直接子节点被创建、被删除、子节点数据发生变更
NodeDataChanged被监听的节点的数据发生变更
NodeDeleted被监听的节点被删除
None 客户端的连接状态(KeeperState)发生变更

拿取事件状态demo

Event.KeeperState state = watchedEvent.getState(); //获取事件的状态
Event.EventType type = watchedEvent.getType(); //获取事件的类型
if (Event.KeeperState.SyncConnected.equals(state)) {
    switch (type) {
        case None:
            log.info("zookeeper connected success");
            countDownLatch.countDown();
            break;
        case NodeCreated:
            log.info("[{}] create node: {}", name, watchedEvent.getPath());
            break;
        case NodeDeleted:
            log.info("[{}] delete node: {}", name, watchedEvent.getPath());
            break;
        case NodeDataChanged:
            log.info("[{}] node data change: {}", name, watchedEvent.getPath());
            break;
        case nodechildrenChanged:
            log.info("[{}] node children change: {}", name, watchedEvent.getPath());
            break;
    }
}

watcher有两种添加方式

  • 使用认watcher boolean watch
List<String> getChildren(String path, boolean watch)
byte[] getData(String path, boolean watch, Stat stat)
Stat exists(String path, boolean watch)

同一方法注册多个事件

zookeeper.exists("/p", true); // 注册认的wachter
zookeeper.exists("/p", new MyWatcher("Customer Watcher")); // 再注册一个watcher
zookeeper.create("/p", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zookeeper.delete("/p", -1);

一个节点注册了多个watcher,那么多个watcher的方法都会被回调。

不同方法注册同一事件多次

zookeeper.create("/p", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zookeeper.getData("/p", true, null); // 注册认的wachter
zookeeper.exists("/p", true); // 注册两次认的wachter
zookeeper.setData("/p", "ppp".getBytes(), -1);
zookeeper.delete("/p", -1);
注册方式NodeCreatednodechildrenChangedNodeDataChangedNodeDeleted
getChildrenYY
existsYYY
getDataYY

通过观察运行结果,总结如下:

  • 注册一次watcher只会收到一次通知,想一直监听就得收到通知后再次注册
  • 一个watcher实例被例如exists,getData等方法多次注册,zookeeper客户端也只会收到一次通知
  • 一个节点注册多个不同的watcher实例时,会通知多次,即每个被注册的watcher都会收到通知
  • exists可以监听一个不存在的节点,但是getData和getChildren不能监控一个不存在的节点,否则会报NoNodeException。

zookeeper原生客户端的缺点

  • 不能递归的创建节点和删除节点。
  • 对节点的数据操作基于字节数组(二进制安全),经常需要数组和字符串之间的转换。
  • 想一直监听某个节点就要一直注册,监听一些不存在的节点可能会抛出异常。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐