zookeeper如何永久监听
转自:http://www.cnblogs.com/viviman/archive/2013/03/11/2954118.html
一 回调基础知识
znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的集中管理,集群管理,分布式锁等等。
//创建一个Zookeeper实例,第一个参数为目标服务器地址和端口,第二个参数为Session超时时间,第三个为节点变化时的回调方法
ZooKeeper zk = new ZooKeeper("127.0.0.1:2181", 500000,new Watcher() {
// 监控所有被触发的事件
public void process(WatchedEvent event) {
//dosomething
}
});
将APP1的所有配置配置到/APP1 znode下,APP1所有机器一启动就对/APP1这个节点进行监控(zk.exist("/APP1",true)),并且实现回调方法Watcher,那么在zookeeper上/APP1 znode节点下数据发生变化的时候,每个机器都会收到通知,Watcher方法将会被执行,那么应用再取下数据即可(zk.getData("/APP1",false,null));
下面表格列出了写操作与ZK内部产生的事件的对应关系:
|
event For “/path” |
event For “/path/child” |
|
|
create(“/path”) |
EventType.NodeCreated |
NA |
|
delete(“/path”) |
EventType.NodeDeleted |
NA |
|
setData(“/path”) |
EventType.NodeDataChanged |
NA |
|
create(“/path/child”) |
EventType.NodeChildrenChanged |
EventType.NodeCreated |
|
delete(“/path/child”) |
EventType.NodeChildrenChanged |
EventType.NodeDeleted |
|
setData(“/path/child”) |
NA |
EventType.NodeDataChanged |
而ZK内部的写事件与所触发的watcher的对应关系如下:
|
event For “/path” |
defaultWatcher |
exists |
getData |
getChildren |
|
EventType.None |
√ |
√ |
√ |
√ |
|
EventType.NodeCreated |
√ |
√ |
||
|
EventType.NodeDeleted |
√(不正常) |
√ |
||
|
EventType.NodeDataChanged |
√ |
√ |
||
|
EventType.NodeChildrenChanged |
√ |
综合上面两个表,我们可以总结出各种写操作可以触发哪些watcher,如下表所示:
|
“/path” |
“/path/child” |
|||||||
|
exists |
getData |
getChildren |
exists |
getData |
getChildren |
|||
|
create(“/path”) |
√ |
√ |
||||||
|
delete(“/path”) |
√ |
√ |
√ |
|||||
|
setData(“/path”) |
√ |
√ |
||||||
|
create(“/path/child”) |
√ |
√ |
√ |
|||||
|
delete(“/path/child”) |
√ |
√ |
√ |
√ |
||||
|
setData(“/path/child”) |
√ |
√ |
||||||
如果发生session close、authFail和invalid,那么所有类型的wather都会被触发
zkClient除了做了一些便捷包装之外,对watcher使用做了一点增强。比如subscribeChildChanges实际上是通过exists和getChildren关注了两个事件。这样当create(“/path”)时,对应path上通过getChildren注册的listener也会被调用。另外subscribeDataChanges实际上只是通过exists注册了事件。因为从上表可以看到,对于一个更新,通过exists和getData注册的watcher要么都会触发,要么都不会触发。
getData,getChildren(),exists()这三个方法可以针对参数中的path设置watcher,当path对应的Node 有相应变化时,server端会给对应的设置了watcher的client 发送一个一次性的触发通知事件。客户端在收到这个触发通知事件后,可以根据自己的业务逻辑进行相应地处理。
注意这个watcher的功能是一次性的,如果还想继续得到watcher通知,在处理完事件后,要重新register。
二 测试watcher回调机制
// Watcher实例
Watcher wh = new Watcher() {
public void process(WatchedEvent event) {
System.out.println("回调watcher实例: 路径" + event.getPath() + " 类型:"
+ event.getType());
}
};
ZooKeeper zk = new ZooKeeper("10.15.82.166:3351", 500000, wh);
System.out.println("---------------------");
// 创建一个节点root,数据是mydata,不进行ACL权限控制,节点为永久性的(即客户端shutdown了也不会消失)
zk.exists("/root", true);
zk.create("/root", "mydata".getBytes(), Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT);
System.out.println("---------------------");
// 在root下面创建一个childone znode,数据为childone,不进行ACL权限控制,节点为永久性的
zk.exists("/root/childone", true);
zk.create("/root/childone", "childone".getBytes(), Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT);
System.out.println("---------------------");
// 删除/root/childone这个节点,第二个参数为版本,-1的话直接删除,无视版本
zk.exists("/root/childone", true);
zk.delete("/root/childone", -1);
System.out.println("---------------------");
zk.exists("/root", true);
zk.delete("/root", -1);
System.out.println("---------------------");
// 关闭session
zk.close();
---------------------
回调watcher实例: 路径null 类型:None
回调watcher实例: 路径/root 类型:NodeCreated
---------------------
回调watcher实例: 路径/root/childone 类型:NodeCreated
---------------------
回调watcher实例: 路径/root/childone 类型:NodeDeleted
---------------------
回调watcher实例: 路径/root 类型:NodeDeleted
---------------------
三 永久回调
3类事件触发wather后就不再作用,也就是所谓的(一次作用),但是,如何永久监听呢?这需要我们再程序逻辑上进行控制,网上有更好的办法,但是,在简单的应用中,可以再wather方法里面再设置监听,这个方法很笨,但是,很有效,达到了预期的效果。

Watcher wh = new Watcher() {
public void process(WatchedEvent event) {
Log.AC_DEBUG("触发回调watcher实例: 路径" + event.getPath() + " 类型:"
+ event.getType());
if (event.getType() == EventType.None) {
try { //
// 判断userauth权限是否能访问userpath
String auth_type = "digest";
zk.addAuthInfo(auth_type, userauth.getBytes());
zk.getData(userpath, null, null);
} catch (Exception e) {
// e.printStackTrace();
Log.AC_ERROR("get node faild:userpath=" + userpath
+ ",auth=" + userauth + " e:" + e.getMessage());
return;
}
Log.AC_INFO("userpath=" + userpath + " userauth=" + userauth);
}
try {
switchinfo = getallswitch(); // 更新userpath和匿名用户路径下的配置信息,监听这些节点
// 监听用户路径节点
Log.AC_DEBUG("lesson user=" + userpath + " node...");
zk.exists(userpath, true); // 监听匿名用户路径节点
Log.AC_DEBUG("lesson user=" + AnonymousUSERpath + " node...");
zk.exists(AnonymousUSERpath, true);
// 监听用户路径下的开关节点
if (zk.exists(userpath, false) != null) {
Log.AC_DEBUG("lesson user=" + userpath
+ " 's swich node...");
List<String> swnodes = zk.getChildren(userpath, true); //
// 监听switch层节点的变化
Iterator<String> it_sw = swnodes.iterator();
while (it_sw.hasNext()) {
String swpath = userpath + "/" + it_sw.next();
Log.AC_DEBUG("lesson user=" + swpath + " node...");
zk.exists(swpath, true);
}
}
} catch (Exception e) {
e.printStackTrace();
Log.AC_ERROR("lesson znode error:" + e.getMessage());
}
}
};
zookeeper如何永久监听的更多相关文章
- Linux 使用NC命令永久监听本地端口
感谢: 冰点阳光 Linux可以使用nc命令来测试网络端口是否正常,类似于telnet命令,但也可以用nc命令来监听本地端口,支持TCP.UDP协议,当我们测试NTP服务网络策略是否正常时,可以使用到 ...
- Zookeeper三个监听案例
一.监听某一节点内容 /** * @author: PrincessHug * @date: 2019/2/25, 14:28 * @Blog: https://www.cnblogs.com/Hel ...
- Zookeeper Curator 事件监听 - 秒懂
目录 写在前面 1.1. Curator 事件监听 1.1.1. Watcher 标准的事件处理器 1.1.2. NodeCache 节点缓存的监听 1.1.3. PathChildrenCache ...
- Zookeeper中Watcher监听实现增删改
8.1 连接方法 package com.zookeeper.day01; import org.apache.zookeeper.*; import java.io.IOException; pub ...
- ZooKeeper 笔记(2) 监听数据变化
ZK中的每个节点都可以存储一些轻量级的数据,这些数据的变化会同步到集群中的其它机器.在应用中程序员可以添加watcher来监听这些数据的变化,watcher只会触发一次,所以触发过后想要继续监听,必须 ...
- Zookeeper 对节点的 watch监听通知是永久的吗?为什么 不是永久的?
不是.官方声明:一个 Watch 事件是一个一次性的触发器,当被设置了 Watch 的数据发生了改变的时候,则服务器将这个改变发送给设置了 Watch 的客户端, 以便通知它们. 为什么不是永久的,举 ...
- .Net客户端监听ZooKeeper节点数据变化
一个很简单的例子,用途是监听zookeeper中某个节点数据的变化,具体请参见代码中的注释 using System; using System.Collections.Generic; using ...
- ZooKeeper(3.4.5) 使用Curator监听事件
转载:http://www.mamicode.com/info-detail-494364.html 标签: ZooKeeper原生的API支持通过注册Watcher来进行事件监听,但是Watcher ...
- ZooKeeper(3.4.5) - 使用 Curator(2.7.0) 监听事件
ZooKeeper原生的API支持通过注册Watcher来进行事件监听,但是Watcher通知是一次性的,因此开发过程中需要反复注册Watcher,比较繁琐.Curator引入了Cache来监听Zoo ...
随机推荐
- ACM——3n+1
3n+1 时间限制(普通/Java):1000MS/3000MS 运行内存限制:65536KByte总提交:937 测试通过:386 描述 对于任意大于1的自然 ...
- linq 多条件查询 where 拼接+分页
首先定义一个静态类 public static class QueryAssembly { /// <summary> /// 返回true /// </summary> // ...
- iOS 图片按比例压缩,指定大小压缩
使用系统方法UIImageJPEGRepresentation(UIimage *image,CGFloat quality)进行图片质量压缩,暂且叫参数quality为压缩比吧,取值范围为0-1. ...
- Core Canvas–Day1
绘制 1.坐标系统: canvas的坐标以左上角为原点,如图 可对canvas的坐标系统进行变换,变换的方式有 平移translate 旋转rotate 缩放scale 创建自定义的变换方式,切变 2 ...
- RPC实现原理(HSF、dubbo) 从头开始(一)
前言 阔别了很久博客园,虽然看了以前写的很多东西感觉好幼稚,但是还是觉得应该把一些自己觉得有用的东西和大家分享.废话不多说,现在开始进入正题. 之前的六年工作经验,呆过了一些大公司,每个在大公司呆过的 ...
- boa服务器问题日志
1. 某一次在登录boa服务器的时候,不知哪里的问题,无法登录「192.168.1.0-192.168.3.255」网段的设备,但是公司IP网段的机器都可以用.最终发现,问题出现在自己的PC添加了浏览 ...
- Cocos2d-x 3.0坐标系详解(转载)
Cocos2d-x 3.0坐标系详解 Cocos2d-x坐标系和OpenGL坐标系相同,都是起源于笛卡尔坐标系. 笛卡尔坐标系 笛卡尔坐标系中定义右手系原点在左下角,x向右,y向上,z向外,OpenG ...
- 【BZOJ2793】【数学】[Poi2012]Vouchers
Description 考虑正整数集合,现在有n组人依次来取数,假设第i组来了x人,他们每个取的数一定是x的倍数,并且是还剩下的最小的x个. 正整数中有m个数被标成了幸运数,问有哪些人取到了幸运数. ...
- IOS 学习日志 2015-3-13
前面几天在看C ,但是没有做笔记,现在在看Objective--C ,开始做笔记,希望每一天都有成长吧 Objective--C 关键字 1 @import 导入 注意<>||" ...
- Redis 3.0.2集群搭建以及相关问题汇总
Redis3 正式支持了 cluster,是为了解决构建redis集群时的诸多不便 (1)像操作单个redis一样操作key,不用操心key在哪个节点上(2)在线动态添加.删除redis节点,不用停止 ...