watcher架构
watcher
实现由三个部分组成
zookeeper
服务端zookeeper
客户端- 客户端的
ZKWatchManager对象
客户端首先将Watcher
注册到服务端,同时将Watcher
对象保存到客户端的watch
管理器中。当Zookeeper
服务端监听的数据状态发生变化时,服务端会主动通知客户端,接着客户端的Watch
管理器会**触发相关Watcher
**来回调相应处理逻辑,从而完成整体的数据发布/订阅
流程
特性 | 说明 |
---|---|
一次性 | watcher 是一次性的,一旦被触发就会移除,再次使用时需要重新注册 |
客户端顺序回调 | watcher 回调是顺序串行执行的,只有回调后客户端才能看到最新的数据状态。一个watcher 回调逻辑不应该太多,以免影响别的watcher 执行 |
轻量级 | WatchEvent 是最小的通信单位,结构上只包含通知状态、事件类型和节点路径,并不会告诉数据节点变化前后的具体内容 |
时效性 | watcher 只有在当前session 彻底失效时才会无效,若在session 有效期内快速重连成功,则watcher 依然存在,仍可接收到通知; |
注册watcher
客户端与服务器的连接状态
KeeperState
:通知状态SyncConnected
:客户端与服务器正常连接时Disconnected
:客户端与服务器断开连接时Expired
:会话session
失效时AuthFailed
:身份认证失败时- 事件类型为:
None
public static ZooKeeper genZkConn(){
CountDownLatch count = new CountDownLatch(1);
ZooKeeper zooKeeper = null;
try {
zooKeeper = new ZooKeeper("hadoop102:2181",5000,(WatchedEvent watchedEvent)->{
if (watchedEvent.getState()== Watcher.Event.KeeperState.SyncConnected){
System.out.println("Zookeeper连接成功");
count.countDown();
}
});
} catch (IOException e) {
e.printStackTrace();
}
return zooKeeper;
}
检查节点
exists方法
检查节点是否存在,第一个参数表示节点路径
,第二个参数表示是否监听这个节点
。同一个节点可以注册多个监听器。
exists(String path, boolean b)
exists(String path, Watcher w)
getType()
获取的值:
NodeCreated
:节点创建NodeDeleted
:节点删除NodeDataChanged
:节点内容
@Test
public void watcherExisted1() throws Exception{
zooKeeper = ZooKeeperUtils.genZkConn();
zooKeeper.exists("/watcher/node1",true);
Thread.sleep(100000);
}
监测到节点被删除,但是Watcher是一次注册一次监测,监测完成后不能继续监测。
@Test
public void watcherExisted2() throws Exception{
zooKeeper = ZooKeeperUtils.genZkConn();
zooKeeper.exists("/watcher/node2", new Watcher() {
@Override
public void process(WatchedEvent event) {
System.out.println("自定义Watcher");
System.out.println("Path = " + event.getPath());
System.out.println("EventType = "+event.getType());
try {
zooKeeper.exists("/watcher/node2",this);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread.sleep(100000);
}
在precoss
方法中再次调用watcher
可以做到持续监测。
getData方法
getData(String path, boolean b, Stat stat)
getData(String path, Watcher w, Stat stat)
getType()
获取的值:
NodeDeleted
:节点删除NodeDataChange
:节点内容发生变化
getChildren方法
getChildren(String path, boolean b)
getChildren(String path, Watcher w)
getType()
获取的值:
NodeChildrenChanged
:子节点发生变化NodeDeleted
:节点删除