Zookeeper watch机制原理
Zookeeper watch机制原理
- 准备工作
- watch示例
- 源码解析
- 总结
准备工作
经过上一小节的学习我们知道ZookeeperServerMain是单机版的服务器主类
我们可以自己写一个ZkClient类
public class ZkClient {public static void main(String[] args) throws IOException, KeeperException, InterruptedException {final CountDownLatch countDownLatch=new CountDownLatch(1);ZooKeeper zooKeeper=new ZooKeeper("localhost:2182",4000, new Watcher() {@Overridepublic void process(WatchedEvent event) {System.out.println(event);if(Event.KeeperState.SyncConnected==event.getState()){//如果收到了服务端的响应事件,连接成功countDownLatch.countDown();}}});countDownLatch.await();//CONNECTEDSystem.out.println(zooKeeper.getState());byte[] data = zooKeeper.getData("/lry",new Watcher(){@Overridepublic void process(WatchedEvent event) {System.out.println(event);}},new Stat());System.out.println(new String(data));System.in.read();//只有getData,getChildren,exist这三个api有watcher}
}
我们还需要一个控制台可以输入命令的主类,ZookeeperMain
进入ZookeeperMain的run方法,把如下代码注释
// String line;
// Method readLine = consoleC.getMethod("readLine", String.class);
// while ((line = (String)readLine.invoke(console, getPrompt())) != null) {// executeLine(line);
// }
并且加上一行代码
这样先启动ZookeeperServerMain,在启动ZookeeperMain我们就可以在控制台手打命令了
watch示例
菜鸟要飞-zookeeper watch
菜鸟上说的很简洁明了,但是有一些小点限于篇幅没有说到,比如:
- 客户端发送给服务器的包不包括watcher对象信息?
- pendingQueue在watch机制中的作用?
- 为什么只需要request.setWatch(true),而不需要把watcher对象发送给服务器?
- 服务器在收到修改命令后触发triggerWatch方法发送xid=-1的事件给客户端后,客户端是如何从pendingQueue拿出watcher对象,然后回调process方法的?
源码解析
ps: 为了截图和阅读方便,针对源码有所改动
客户端getData之后发送数据流程
wcb在packet里,packet在outgoingQueue里,ClientCnxn的内部类SendThread的run方法把outgoingQueue给了ClientCnxnSocket类ClientCnxnSocketNio继承ClientCnxnSocket,所以最终ClientCnxnSocketNio负责从outgoingQueue取出packet发送部分数据给服务端。
ClientCnxn的内部类SendThread的run方法 的 doTranport() —>ClientCnxnSocketNio.doTranport()---->ClientCnxnSocketNio.doIO()
下面看看服务器收到这条消息会做什么
有了前一篇博客的铺垫,我们直接进入FinalRequestProcessor,找到processRequest方法的case getData
到此服务器就把getData需要的数据返回给了客户端(这里我们不去看客户端接受这个数据的过程),服务端还把watch保存到map里面去了,下面我们看看服务器收到修改命令触发watch的流程
同样是FinalRequestProcessor的processRequest方法
最终会调用到DataTree的processTxn方法
至此服务器的watch就解析完毕,接下来看看客户端接到这个nodechanged事件是如何处理的
ClientCnxn的SendThread线程负责接受和发送数据,最终会调用到ClientCnxnSocketNIO的doIO方法
再进入ClientCnxn的readResponse的case xid=-1
看到这幅图其实有点奇怪,因为我们源码分析到现在都没有看到dataWatches这个map是如何把path对应的wathcer put进去的,其实这是getData后服务器返回数据给客户端,这跟客户端接受数据流程有关,我待会再附加里说这个吧。
但是除此之外,watcher就到waitingEvents队列里了,我们看看ClientCnxn的run方法
附加:说明pendingQueue作用和 客户端的ZKWatchManager类的dataWatches, childWatches, existsWatches是怎么put watcher的
接受数据地方:
ClientCnxn的SendThread的readResponse方法
完整的packet是从pendingQueue拿到的,也是它保存了watcher信息,因为watcher并没有在服务器和客户端之前传送
真正往dataWatches put<path,Watcher>
总结
watch机制确实绕来绕去的,一共要绕四次,客户端两次,服务端两次,zookeeper3.6提供了持久化watch和递归持久化watch,其中持久化做法其实非常简单
remove改成get即可,源码也确实是这么做的,还添加了一个addWatch api,可以对不同的操作watch
Zookeeper watch机制原理相关推荐
- Zookeeper——选举机制原理与Leader和Follower作用
摘要 本博文主要介绍Zookeeper的选举机制的原理与Zookeeper事务请求处理的原理. 一.zookeeper选举算法原理 Leader 服务器的作用是管理 ZooKeeper 集群中的其他服 ...
- zookeeper 分布式锁原理
zookeeper 分布式锁原理: 1 大家也许都很熟悉了多个线程或者多个进程间的共享锁的实现方式了,但是在分布式场景中我们会面临多个Server之间的锁的问题,实现的复杂度比较高.利用基于googl ...
- Kafka设计解析(八)- Exactly Once语义与事务机制原理
本文转发自技术世界,原文链接 http://www.jasongj.com/kafka/transaction/ 写在前面的话 本文所有Kafka原理性的描述除特殊说明外均基于Kafka 1.0.0版 ...
- ZooKeeper的工作原理
ZooKeeper是一个分布式的应用程序协调服务. 2 ZooKeeper的工作原理 Zookeeper 的核心是原子广播,这个机制保证了各个Server之间的同步.实现这个机制的协议叫做Zab ...
- 格式化zookeeper命令_zookeeper原理篇Zookeeper的数据存储与恢复原理
前言 经过前面的一些文章的学习和了解,我们对Zookeeper有了一定的理解. 前文直达链接: zookeeper原理篇-Zookeeper选举过程分析 zookeeper原理篇-Zookeeper会 ...
- zookeeper watch java_Apache ZooKeeper Watcher 机制源码解释
分布式系统从根本上来说就是不同节点上的进程并发执行,并且相互之间对进程的行为进行协调处理的过程.不同节点上的进程互相协调行为的过程叫做分布式同步.许多分布式系统需要一个进程作为任务的协调者,执行一些其 ...
- ZooKeeper学习总结(4)——Zookeeper选举机制总结
Zookeeper 是一个分布式服务框架,主要是用来解决分布式应用中遇到的一些数据管理问题如:统一命名服务.状态同步服务.集群管理.分布式应用配置项的管理等.我们可以简单把 Zookeeper 理解为 ...
- Hadoop生态圈-Zookeeper的工作原理分析
Hadoop生态圈-Zookeeper的工作原理分析 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 无论是是Kafka集群,还是producer和consumer都依赖于Zoo ...
- Zookeeper选举算法原理
Zookeeper选举算法原理 Leader选举 Leader选举是保证分布式数据一致性的关键所在.当Zookeeper集群中的一台服务器出现以下两种情况之一时,需要进入Leader选举. (1) 服 ...
最新文章
- php 空格zhuanyi,php写的将逗号、空格、回车分...-php字符转义的相关注意事项-IIS环境中防止本地用户用fsockopen进行DDOS攻击的方法_169IT.COM...
- Spring Boot和Feign中使用Java 8时间日期API(LocalDate等)的序列化问题
- vim去掉windows文本的多余的回车符(^M)
- linux高通平台代码,高通linux系统初始化
- 51Nod 1640 - 天气晴朗的魔法(最小生成树变形)
- Java代码质量监控工具Sonar安装
- 为什么现代系统需要一个新的编程模型?
- [我的理解]Javascript的原型与原型链
- Dubbo学习总结(6)——Dubbo开源现状与未来规划
- MyBatis基于Java API配置
- makefile中伪目标的理解
- 【定位问题】基于matlab GUI RSSI无线定位【含Matlab源码 1054期】
- 【时间序列分析】14.平稳序列的参数估计与白噪声检验
- Python3: chardet 检测 bytes 的原字符串编码格式
- 螺丝螺母垫片顺序图片_如何计算螺丝,螺栓和螺母的尺寸
- 转载 基于MATLAB 进行图像分类
- 高性能网站架构之缓存篇—Redis集群搭建
- 响应式banner图片轮播布局代码
- 用python爬取全国315个城市肯德基老爷爷的店面信息,看看又是什么神奇的发现
- 丁华锋 机器人_国家重点研发计划“智能机器人”项目在西安交大启动