Java教程

zookeeper04-Java Api(2)事件监听

本文主要是介绍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)
  • 自定义watcher Watcher watcher

同一方法注册多个事件

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原生客户端的缺点

  • 不能递归的创建节点和删除节点。
  • 对节点的数据操作基于字节数组(二进制安全),经常需要数组和字符串之间的转换。
  • 想一直监听某个节点就要一直注册,监听一些不存在的节点可能会抛出异常。
这篇关于zookeeper04-Java Api(2)事件监听的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!