通过ZooKeeper命令行工具,我们可以看到:ZooKeeper的很多命令都带有一个[watch]参数,接下来实践一下ZooKeeper的事件监听----Watch机制
Watcher 监听机制是 Zookeeper 中非常重要的特性,我们基于 zookeeper 上创建的节点,可以对这些节点绑定监听事件。比如可以监听节点数据变更、节点删除、子节点状态变更等事件,通过这个事件机制,可以实现:基于 zookeeper 实现分布式锁、集群管理等功能。
Watcher 特性:当数据发生变化的时候, zookeeper 会产生一个 watcher 事件,并且会发送到客户端。但是客户端只会收到一次通知。如果后续这个节点再次发生变化,那么之前设置 watcher 的客户端不会再次收到消息(watcher 是一次性的操作),可以通过循环监听去达到永久监听效果 。
ZooKeeper的Java API中,可以通过getData()方法、Exists()方法、getChildren()方法来绑定监听事件,凡是所有的事务型的操作(增、删、改),都会触发到监听事件
Watcher监听事件
None(-1), 客户端连接状态发生变化的时候,会收到None的事件 NodeCreated(1), 创建节点的事件 NodeDeleted(2), 删除节点的事件 NodeDataChanged(3), 节点数据发生变更 NodeChildrenChanged(4); 子节点被创建、被删除,会发生事件触发
什么样的操作会产生什么类型的事件
监听父节点 | 监听子节点 | |
create(父节点) | NodeCreated | 无 |
delete(父节点) | NodeDeleted | 无 |
setData(父节点) | NodeDataChanged | 无 |
create(子节点) | NodeChildrenChanged | NodeCreated |
delete(子节点) | NodeChildrenChanged | NodeDeleted |
setData(子节点) | 无 | NodeDataChanged |
Java API Watcher监听Demo
/**
* ZooKeeper监听实例
*/
public class WatcherDemo {
public static void main(String[] args) {
try {
final CountDownLatch countDownLatch=new CountDownLatch(1);
//watch机制(回调),监听是否连接成功
final ZooKeeper zooKeeper = new ZooKeeper("192.168.204.201:2181,192.168.204.202:2181,192.168.204.203:2181", 4000, new Watcher() {
public void process(WatchedEvent watchedEvent) {
//初次进入,此处会监听到事件
System.out.println("默认事件:"+watchedEvent.getType());
if(Event.KeeperState.SyncConnected == watchedEvent.getState()){
//如果受收到了服务端的响应事件,连接成功
countDownLatch.countDown();
}
}
});
countDownLatch.await();
//创建节点
zooKeeper.create("/zk-lzb", "11".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//只可以通过getData、Exists、getChildren这三个操作,来完成事件绑定
Stat stat = zooKeeper.exists("/zk-lzb", new Watcher() {
public void process(WatchedEvent watchedEvent) {
System.out.println("监听节点:"+watchedEvent.getPath() + " 监听类型:"+watchedEvent.getType());
}
});
//此处会被监听到
stat = zooKeeper.setData("/zk-lzb", "lzb".getBytes(), stat.getVersion());
//因为watcher是一次性的操作,所以此处不会监听
zooKeeper.delete("/zk-lzb",stat.getVersion());
zooKeeper.exists("/zk-lzb-2", new Watcher() {
public void process(WatchedEvent watchedEvent) {
System.out.println("监听节点:"+watchedEvent.getPath() + " 监听类型:"+watchedEvent.getType());
}
});
zooKeeper.create("/zk-lzb-2", "11".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (KeeperException e) {
e.printStackTrace();
}
}
}
执行结果:
默认事件:None
监听节点:/zk-lzb 监听类型:NodeDataChanged
监听节点:/zk-lzb-2 监听类型:NodeCreated
通过watcher实现永久监听,有待继续研究
如有资料,请告知一下,谢谢啦
博主写作不易,来个关注呗
求关注、求点赞,加个关注不迷路 ヾ(◍°∇°◍)ノ゙
博主不能保证写的所有知识点都正确,但是能保证纯手敲,错误也请指出,望轻喷 Thanks♪(・ω・)ノ