本文将介绍Zookeeper提供的三种监听类型
官方说明:一个Watch事件是一个一次性的触发器,当被设置了Watch的数据发生了改变的时候,则服务器将这个改变发送给设置了Watch的客户端,以便通知它们
代码地址:https://gitee.com/webprogram/springboot_zookeeper
Watch监听
- Zookeeper允许用户在指定节点上注册一些watcher,并且在一些特定事件触发的时候,Zookeeper服务端会将事件通知到感兴趣的客户端上去,该机制是Zookeeper实现分布式协调服务的重要特性
- Zookeeper中引入了watcher机制来实现了发布和订阅功能,能够让多个订阅者同时监听某一对象,当一个对象自身状态变化是,会通知所有订阅者
- Zookeeper原生迟滞通过注册watcher来进行事件监听,但是其使用并不是特别方便,需要开发人员自己反复注册watcher,比较繁琐
- curator引入了cache来实现对Zookeeper服务端事件的监听
- Zookeeper提供了三种watcher:
- NodeCache:只是监听某一个特定的节点
- PathChildrenCache:监控一个ZNode的子节点
- TreeCache:可以监控整个树上的所有节点,类似于PathChildrenCache和NodeCache的组合
NodeCache 操作某一节点会被监听
/**
* @description: 监听某个节点
*/
@Test
public void watcherNodeCache() throws Exception {
//1.创建NodeCache对象
final NodeCache nodeCache = new NodeCache(curatorClient, "/k1");
//2.注册监听
nodeCache.getListenable().addListener(new NodeCacheListener(){
public void nodeChanged() throws Exception {
System.out.println("监听到了改变");
// 获取改变后的值
byte[] value = nodeCache.getCurrentData().getData();
System.out.println(new String(value));
}
});
//3.开启监听,如果设置为true,则开启监听时加载缓存数据
nodeCache.start(true);
// 此处死循环,用来阻断程序运行结束,可在命令行操作节点来测试监听,当修改节点值或删除节点会被监听到
while(true){}
}
PathChildrenCache 操作子节点会被监听
/**
* @description: 监听某个节点的所有子节点
*/
@Test
public void watcherPathChildrenCache() throws Exception {
//1.创建PathChildrenCache对象
final PathChildrenCache pathChildrenCache = new PathChildrenCache(curatorClient,"/", true);
//2.注册监听
pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener(){
public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception {
System.out.println("监听到了改变");
// 获取改变后的信息
// 打印结果:{type=CHILD_UPDATED, data=ChildData{path='/k4', stat=72,78,1630823414010,1630823833164,3,0,0,0,3,0,72
//, data=[118, 118, 52]}}
System.out.println(pathChildrenCacheEvent);
// 判断为特定类型时,进行逻辑处理 一般只关注新增、删除、修改
PathChildrenCacheEvent.Type type = pathChildrenCacheEvent.getType();
if(type.equals(PathChildrenCacheEvent.Type.CHILD_ADDED)
|| type.equals(PathChildrenCacheEvent.Type.CHILD_REMOVED)
|| type.equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)){
// 为什么获取值两次getData(), 查看上方event对象对应的json串 data[]字节数组外面还有层data{}对象
System.out.println("改变后的值为:" + new String(pathChildrenCacheEvent.getData().getData()));
}
}
});
//3.开启监听
pathChildrenCache.start();
// 此处死循环,用来阻断程序运行结束,可在命令行操作节点来测试监听
while(true){}
}
TreeCache 监听自身节点及子节点
/**
* @description: 监听自身及子节点
*/
@Test
public void watcherTreeCache() throws Exception {
//1.创建PathChildrenCache对象
final TreeCache treeCache = new TreeCache(curatorClient,"/");
//2.注册监听
treeCache.getListenable().addListener(new TreeCacheListener(){
public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception {
System.out.println("监听到了改变");
// 获取改变后的信息
// 打印结果:{type=CHILD_UPDATED, data=ChildData{path='/k4', stat=72,78,1630823414010,1630823833164,3,0,0,0,3,0,72
//, data=[118, 118, 52]}}
System.out.println(treeCacheEvent);
// 判断为特定类型时,进行逻辑处理 一般只关注新增、删除、修改
TreeCacheEvent.Type type = treeCacheEvent.getType();
if(type.equals(TreeCacheEvent.Type.NODE_ADDED)
|| type.equals(TreeCacheEvent.Type.NODE_REMOVED)
|| type.equals(TreeCacheEvent.Type.NODE_UPDATED)){
// 为什么获取值两次getData(), 查看上方event对象对应的json串 data[]字节数组外面还有层data{}对象
System.out.println("改变后的值为:" + new String(treeCacheEvent.getData().getData()));
}
}
});
//3.开启监听
treeCache.start();
// 此处死循环,用来阻断程序运行结束,可在命令行操作节点来测试监听
while(true){}
}