4、zookeeper的事件监听机制
watcher概念
https://zookeeper.apache.org/doc/r3.4.14/zookeeperProgrammers.html#sc_WatchRememberThese
zookeeper提供了数据的发布/订阅功能,多个订阅者可同时监听某一特定主题对象,当该主题对象的自身状态发生变化时例如节点内容改变、节点下的子节点列表改变等,会实时、主动通知所有订阅者zookeeper采用了Watcher机制实现数据的发布订阅功能。该机制在被订阅对象发生变化时会异步通知客户端,因此客户端不必在Watcher注册后轮询阻塞,从而减轻了客户端压力watcher机制事件上与观察者模式类似,也可看作是一种观察者模式在分布式场景下的实现方式
watcher架构
watcher实现由三个部分组成
zookeeper服务端zookeeper客户端客户端的
ZKWatchManager对象
客户端首先将 Watcher注册到服务端,同时将 Watcher对象保存到客户端的watch管理器中。当Zookeeper服务端监听的数据状态发生变化时,服务端会主动通知客户端,接着客户端的 Watch管理器会触发相关 Watcher来回调相应处理逻辑,从而完成整体的数据 发布/订阅流程

watcher特性
特性 说明 一次性 watcher是一次性的,一旦被触发就会移除,再次使用时需要重新注册客户端顺序回调 watcher回调是顺序串行执行的,只有回调后客户端才能看到最新的数据状态。一个watcher回调逻辑不应该太多,以免影响别的watcher执行轻量级 WatchEvent是最小的通信单位,结构上只包含通知状态、事件类型和节点路径,并不会告诉数据节点变化前后的具体内容时效性 watcher只有在当前session彻底失效时才会无效,若在session有效期内快速重连成功,则watcher依然存在,仍可接收到通知;
watcher接口设计
Watcher是一个接口,任何实现了Watcher接口的类就算一个新的Watcher。Watcher内部包含了两个枚举类:KeeperState、EventType

Watcher通知状态(KeeperState)
KeeperState是客户端与服务端连接状态发生变化时对应的通知类型。路径为org.apache.zookeeper.Watcher.EventKeeperState,是一个枚举类,其枚举属性如下:
枚举属性 说明 SyncConnected客户端与服务器正常连接时 Disconnected客户端与服务器断开连接时 Expired会话 session失效时AuthFailed身份认证失败时
Watcher事件类型(EventType)
EventType是数据节点znode发生变化时对应的通知类型。EventType变化时KeeperState永远处于SyncConnected通知状态下;当keeperState发生变化时,EventType永远为None。其路径为org.apache.zookeeper.Watcher.Event.EventType,是一个枚举类,枚举属性如下:
枚举属性 说明 None无 NodeCreatedWatcher监听的数据节点被创建时NodeDeletedWatcher监听的数据节点被删除时NodeDataChangedWatcher监听的数据节点内容发生更改时(无论数据是否真的变化)NodeChildrenChangedWatcher监听的数据节点的子节点列表发生变更时注意:客户端接收到的相关事件通知中只包含状态以及类型等信息,不包含节点变化前后的具体内容,变化前的数据需业务自身存储,变化后的数据需要调用
get等方法重新获取
捕获相应的事件
上面讲到zookeeper客户端连接的状态和zookeeper对znode节点监听的事件类型,下面我们来讲解如何建立zookeeper的watcher监听。在zookeeper中采用zk.getChildren(path,watch)、zk.exists(path,watch)、zk.getData(path,watcher,stat)这样的方式来为某个znode注册监听 。
下表以node-x节点为例,说明调用的注册方法和可用监听事件间的关系:
| 注册方式 | created | childrenChanged | Changed | Deleted |
|---|---|---|---|---|
zk.exists("/node-x",watcher) |
可监控 | 可监控 | 可监控 | |
zk.getData("/node-x",watcher) |
可监控 | 可监控 | ||
zk.getChildren("/node-x",watcher) |
可监控 | 可监控 |
注册watcher的方法
客户端与服务器端的连接状态
KeeperState:通知状态SyncConnected:客户端与服务器正常连接时Disconnected:客户端与服务器断开连接时Expired:会话session失效时AuthFailed:身份认证失败时事件类型为:
None
public class ZkConnectionWatcher implements Watcher {
@Override
public void process(WatchedEvent watchedEvent) {
Event.KeeperState state = watchedEvent.getState();
if(state == Event.KeeperState.SyncConnected){
// 正常
System.out.println("正常连接");
}else if (state == Event.KeeperState.Disconnected){
// 可以用Windows断开虚拟机网卡的方式模拟
// 当会话断开会出现,断开连接不代表不能重连,在会话超时时间内重连可以恢复正常
System.out.println("断开连接");
}else if (state == Event.KeeperState.Expired){
// 没有在会话超时时间内重新连接,而是当会话超时被移除的时候重连会走进这里
System.out.println("连接过期");
}else if (state == Event.KeeperState.AuthFailed){
// 在操作的时候权限不够会出现
System.out.println("授权失败");
}
countDownLatch.countDown();
}
private static final String IP = "192.168.133.133:2181"
;
private static CountDownLatch countDownLatch = new CountDownLatch(1);
public static void main(String[] args) throws Exception {
// 5000为会话超时时间
ZooKeeper zooKeeper = new ZooKeeper(IP, 5000, new ZkConnectionWatcher());
countDownLatch.await();
// 模拟授权失败
zooKeeper.addAuthInfo("digest1","itcast1:123451".getBytes());
byte[] data = zooKeeper.getData("/hadoop", false, null);
System.out.println(new String(data));
TimeUnit.SECONDS.sleep(50);
}
}
watcher检查节点
exists
exists(String path, boolean b)exists(String path, Watcher w)NodeCreated:节点创建NodeDeleted:节点删除NodeDataChanged:节点内容
public class EventTypeTest {
private static final String IP = "192.168.133.133:2181";
private static CountDownLatch countDownLatch = new CountDownLatch(1);
private static ZooKeeper zooKeeper;
// 采用zookeeper连接创建时的监听器
public static void exists1() throws Exception{
zooKeeper.exists("/watcher1",true);
}
// 自定义监听器
public static void exists2() throws Exception{
zooKeeper.exists("/watcher1",(WatchedEvent w) -> {
System.out.println("自定义" + w.getType());
});
}
// 演示使用多次的监听器
public static void exists3() throws Exception{
zooKeeper.exists("/watcher1", new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
try {
System.out.println("自定义的" + watchedEvent.getType());
} finally {
try {
zooKeeper.exists("/watcher1",this);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
// 演示一节点注册多个监听器
public static void exists4() throws Exception{
zooKeeper.exists("/watcher1",(WatchedEvent w) -> {
System.out.println("自定义1" + w.getType());
});
zooKeeper.exists("/watcher1", new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
try {
System.out.println("自定义2" + watchedEvent.getType());
} finally {
try {
zooKeeper.exists("/watcher1",this);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
// 测试
public static void main(String[] args) throws Exception {
zooKeeper = new ZooKeeper(IP, 5000, new ZKWatcher());
countDownLatch.await();
exists4();
TimeUnit.SECONDS.sleep(50);
}
static class ZKWatcher implements Watcher{
@Override
public void process(WatchedEvent watchedEvent) {
countDownLatch.countDown();
System.out.println("zk的监听器" + watchedEvent.getType());
}
}
}
getData
getData(String path, boolean b, Stat stat)getData(String path, Watcher w, Stat stat)NodeDeleted:节点删除NodeDataChange:节点内容发生变化
getChildren
getChildren(String path, boolean b)getChildren(String path, Watcher w)NodeChildrenChanged:子节点发生变化NodeDeleted:节点删除
4、zookeeper的事件监听机制的更多相关文章
- 4.JAVA之GUI编程事件监听机制
事件监听机制的特点: 1.事件源 2.事件 3.监听器 4.事件处理 事件源:就是awt包或者swing包中的那些图形用户界面组件.(如:按钮) 事件:每一个事件源都有自己特点有的对应事件和共性事件. ...
- .NET事件监听机制的局限与扩展
.NET中把“事件”看作一个基本的编程概念,并提供了非常优美的语法支持,对比如下C#和Java代码可以看出两种语言设计思想之间的差异. // C#someButton.Click += OnSomeB ...
- 关于事件监听机制的总结(Listener和Adapter)
记得以前看过事件监听机制背后也是有一种设计模式的.(设计模式的名字记不清了,只记得背后实现的数据结构是数组.) 附上事件监听机制的分析图: 一个事件源可以承载多个事件(只要这个事件源支持这个事件就可以 ...
- GUI编程笔记(java)05:GUI事件监听机制原理和举例说明
1.事件监听机制: A:事件源 事件发生的地方 B:事件 就是要发生的事情 C:事件处理 就是针对发生的事情做 ...
- JAVA事件监听机制学习
//事件监听机制 import java.awt.*; import java.awt.event.*; public class TestEvent { public static void mai ...
- Java中的事件监听机制
鼠标事件监听机制的三个方面: 1.事件源对象: 事件源对象就是能够产生动作的对象.在Java语言中所有的容器组件和元素组件都是事件监听中的事件源对象.Java中根据事件的动作来区分不同的事件源对象,动 ...
- java Gui编程 事件监听机制
1. GUI编程引言 以前的学习当中,我们都使用的是命令交互方式: 例如:在DOS命令行中通过javac java命令启动程序. 软件的交互的方式: 1. 命令交互方式 图书管理系统 ...
- Java swing(awt):事件监听机制的实现原理+简单示例
(1)实现原理 事件监听机制的实现: 参考图:事件模型_ActionEvent 为了节省资源,系统无法对某个事件进行实时的监听.故实现的机制是当发生某个事件后,处理代码将被自动运行,类似钩子一般.(回 ...
- JAVA之旅(三十一)——JAVA的图形化界面,GUI布局,Frame,GUI事件监听机制,Action事件,鼠标事件
JAVA之旅(三十一)--JAVA的图形化界面,GUI布局,Frame,GUI事件监听机制,Action事件,鼠标事件 有段时间没有更新JAVA了,我们今天来说一下JAVA中的图形化界面,也就是GUI ...
- 简单剖析Node中的事件监听机制(一)
使用js的class类简单的实现一个事件监听机制,不同于浏览器中的时间绑定与监听,类似于node中的时间监听,并且会在接下来的文章中去根据自己的理解去写一下Event模块中的原理. Node.js使用 ...
随机推荐
- ABP vNext系列文章01---模块化
一.模块化应用 1.继承AbpModule 每个模块都应该定义一个模块类.定义模块类的最简单方法是创建一个派生自AbpModule的类,如下所示: 2.配置依赖注入和其他模块---ConfigSe ...
- 使用Python调用Nessus 接口实现自动化扫描
@ 目录 认证 策略模板配置 创建策略模板 任务 创建任务 启动/停止任务 获取扫描结果 获取漏洞信息 获取漏洞输出信息与漏洞知识库信息 最后总结 之前在项目中需要接入nessus扫描器,研究了一下n ...
- 【1】windows系统如何安装后缀是whl的python库
相关文章: 全网最详细超长python学习笔记.14章节知识点很全面十分详细,快速入门,只用看这一篇你就学会了! [1]windows系统如何安装后缀是whl的python库 [2]超级详细Pytho ...
- 20.4 OpenSSL 套接字AES加密传输
在读者了解了加密算法的具体使用流程后,那么我们就可以使用这些加密算法对网络中的数据包进行加密处理,加密算法此处我们先采用AES算法,在网络通信中,只需要在发送数据之前对特定字符串进行加密处理,而在接收 ...
- 2.11 PE结构:添加新的节区
在可执行PE文件中,节(section)是文件的组成部分之一,用于存储特定类型的数据.每个节都具有特定的作用和属性,通常来说一个正常的程序在被编译器创建后会生成一些固定的节,通过将数据组织在不同的节中 ...
- C/C++ 内存转储与获取DLL加载
CREATE_PROCESS_DEBUG_EVENT 创建进程的调试事件.CREATE_PROCESS_DEBUG_INFO结构体描述了该类调试事件的详细信息 OUTPUT_DEBUG_STRING_ ...
- 辣鸡 mac 下 pycharm 中代码拖拽的问题
Editor –> General Enable Drag'n'Drop functionality in Editor
- 基于.NET的机械运动模拟应用开发
1 简介 机械运动在物理学中,把一个物体相对于另一个物体位置的变化称作为机械运动,简称运动.机械运动是指一个物体相对于其他物体的位置发生改变,是自然界中最简单,最基本的运动形态. 自然界中一切物体都在 ...
- MySQL数据库详解(上)
MySQL(一) 1.登陆 mysql -uroot -pMyPassword 使用默认的root用户名登陆,将MyPassword改成自己的密码 2.基本操作 --注释 updata mysql . ...
- Linux--Vi编辑命令(跳到指定行、翻屏、缩进)
1.设置行号 如果编辑后,又想显示行号,同样操作按一下esc键,并输入:(冒号),输入set number ,并按回车键,完成后即显示行号. 不需要显示行号,同样操作按一下esc键,并输入:(冒 ...