zookeeper 获取节点信息,zk提供了四个构造函数,其中两个是同步请求,另外两个是异步请求。
  1. public byte[] getData(String path, Watcher watcher, Stat stat)
  2. public byte[] getData(String path, boolean watch, Stat stat)
  3. public void getData(String path, Watcher watcher, DataCallback cb, Object ctx)
  4. public void getData(String path, boolean watch, DataCallback cb, Object ctx)

在这四个构造函数当中,重点主要讲解第一个和第三个构造函数。第二个构造函数间接调用了第一个构造函数,通过参数是否监听标识来判断是否使用默认的监听对象;对于第四个构造函数也是如此,间接也调用了第三个构造函数。

   //第二个构造函数public byte[] getData(String path, boolean watch, Stat stat) throws KeeperException, InterruptedException {return this.getData(path, watch ? this.watchManager.defaultWatcher : null, stat);}// 第四个构造函数public void getData(String path, boolean watch, DataCallback cb, Object ctx) {this.getData(path, watch ? this.watchManager.defaultWatcher : null, cb, ctx);}
1 同步请求获取节点数据
 public byte[] getData(String path, Watcher watcher, Stat stat) throws KeeperException, InterruptedException {// 验证节点路径的合法性PathUtils.validatePath(path);// 初始化监听注册对象为空ZooKeeper.WatchRegistration wcb = null;// 判断监听对象是否为空,如果不为空,new一个数据监听注册对象if (watcher != null) {wcb = new ZooKeeper.DataWatchRegistration(watcher, path);}// 拼接zk根节点String serverPath = this.prependChroot(path);// 封装请求头RequestHeader h = new RequestHeader();h.setType(4);GetDataRequest request = new GetDataRequest();request.setPath(serverPath);request.setWatch(watcher != null);GetDataResponse response = new GetDataResponse();// 通过客户端cnxn将该次的请求添加到sendThread线程队列中ReplyHeader r = this.cnxn.submitRequest(h, request, response, wcb);if (r.getErr() != 0) {throw KeeperException.create(Code.get(r.getErr()), path);} else {if (stat != null) {DataTree.copyStat(response.getStat(), stat);}return response.getData();}}

重点在于
this.cnxn.submitRequest(h, request, response, (ZooKeeper.WatchRegistration)null);这个方法的处理逻辑,继续看下submitRequest 做了什么东西。该方法是在ClientCnxn类中,客户端与服务端的交互处理主要在该类中。

 public ReplyHeader submitRequest(RequestHeader h, Record request, Record response, WatchRegistration watchRegistration) throws InterruptedException {       // new 一个响应头,主要是接收从服务器响应回来的信息ReplyHeader r = new ReplyHeader();// 将请求数据组装成一个packet,跟服务端交互最小的单元,并且添加到请求队列里ClientCnxn.Packet packet = this.queuePacket(h, r, request, response, (AsyncCallback)null, (String)null, (String)null, (Object)null, watchRegistration);synchronized(packet) {// 同步请求,等待服务器响应回来while(!packet.finished) {packet.wait();}return r;}}

请求节点数据的源码跟创建节点的源码逻辑是不是很类似,每次请求都会将该请求添加到发送消息队列,由客户端发送线程去发送请求,并响应回来到客户端。只不过在zk获取节点数据时候,我们可以注册一个监听对象,当获取节点对象的内容发生变化时,客户端能够获取到服务器最新的数据。比如说集群里某个客户端的配置信息发生改变时,集群里的其他客户端能够第一时间感知,并获取最新配置信息。
DataWatchRegistration 的父类是WatchRegisistration ,该父类有四个子类,分别对应不同的监听注册类型,根据不同的操作类型将watcher对象注册到不同的注册器里

2 异步请求获取节点数据
 public void getData(String path, Watcher watcher, DataCallback cb, Object ctx) {PathUtils.validatePath(path);ZooKeeper.WatchRegistration wcb = null;if (watcher != null) {wcb = new ZooKeeper.DataWatchRegistration(watcher, path);}String serverPath = this.prependChroot(path);RequestHeader h = new RequestHeader();h.setType(4);GetDataRequest request = new GetDataRequest();request.setPath(serverPath);request.setWatch(watcher != null);GetDataResponse response = new GetDataResponse();this.cnxn.queuePacket(h, new ReplyHeader(), request, response, cb, path, serverPath, ctx, wcb);}

同步和异步请求的区别在于,客户端发送数据后,有没有等待服务器响应回来;对于异步请求而言,关注的是,只要将获取数据的请求添加到客户端发送消息队列里就行,等待服务器响应回来后,会自动调用之前传入的回调接口并执行processResult方法。

即可以比对下异步和同步的代码,可以看到同步请求会多异步请求一个操作,就是一直在等待服务器的响应,判断packet状态是否是成功,如果是成功则返回服务器响应回来的数据。

思考:客户端如何注册监听?请求回来后客户端如何回调监听?服务端怎么样处理监听?

【zookeeper 获取节点数据getData源码解析】相关推荐

  1. Dubbo 实现原理与源码解析系列 —— 精品合集

    摘要: 原创出处 http://www.iocoder.cn/Dubbo/good-collection/ 「芋道源码」欢迎转载,保留摘要,谢谢! 1.[芋艿]精尽 Dubbo 原理与源码专栏 2.[ ...

  2. 【开源项目】Sa-Token快速登录(使用+源码解析)

    什么是Sa-Token 官网:https://sa-token.dev33.cn Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证.权限认证.Session会话.单点登录.O ...

  3. btcd源码解析——peer节点之间的区块数据同步 (3) —— 非headersFirstMode模式

    文章目录 1. 写在前面 2. 非headersFirstMode模式下的数据同步过程 2.1 peer A 发送"获取区块哈希"的请求 2.2 peer B 响应"获取 ...

  4. dubbo源码解析-zookeeper创建节点

    前言 在之前dubbo源码解析-本地暴露中的前言部分提到了两道高频的面试题,其中一道dubbo中zookeeper做注册中心,如果注册中心集群都挂掉,那发布者和订阅者还能通信吗?在上周的dubbo源码 ...

  5. Zookeeper源码解析 -- 本地事务日志持久化之FileTxnLog

    序言 在各个分布式组件中,持久化数据到本地的思想并不少见,为的是能保存内存中的数据,以及重启后能够重载上次内存状态的值.那么如何行之有效的进行,内存数据持久化到磁盘,怎么样的落盘策略合适,怎么设计持久 ...

  6. 源码解析-深刻理解Hash HashTable HashMap原理及数据hash碰撞问题

    HashMap 前言 Hash HashTable 开地址法 线性探测法 平方探测法 双重散列探测法 拉链法 哈希表优势 HashMap 变量介绍 初始容量和负载因子 红黑树和链表转化 HashMap ...

  7. Python数据爬取之0基础小白实战(三)源码解析

    前两篇(一)软件安装.(二)初窥门槛我解决了软件版本不匹配的问题并学习关键技术.找到重要源码,完成了程序思路总体设计,本篇废话不多说,我们直接上源码. 任务描述 获取2015-2020年通过申请的国家 ...

  8. Dubbo源码解析 —— Zookeeper 订阅

    作者:肥朝 原文地址:https://www.jianshu.com/p/73224a6c07bb 友情提示:欢迎关注公众号[芋道源码].????关注后,拉你进[源码圈]微信群和[肥朝]搞基嗨皮. 友 ...

  9. 谷歌BERT预训练源码解析(一):训练数据生成

    目录 预训练源码结构简介 输入输出 源码解析 参数 主函数 创建训练实例 下一句预测&实例生成 随机遮蔽 输出 结果一览 预训练源码结构简介 关于BERT,简单来说,它是一个基于Transfo ...

  10. dataset__getitem___PyTorch源码解析与实践(1):数据加载Dataset,Sampler与DataLoader

    献给学习PyTorch在路上或者计划较深入理解PyTorch的同行者们 写在前面 笔者一直使用tf,大势所趋决定转PyTorch,这个系列就作为我学习PyTorch的笔记与心得. 网络上PyTorch ...

最新文章

  1. linux 知识汇总
  2. 5训练需要更改参数吗_这就是需要的瘦肚子训练,5个杠铃片腹肌训练动作暴汗燃脂瘦腰腹...
  3. 多平台支持:下一步容器技术热点
  4. C语言数据结构与算法
  5. python怎么接外活_Python三大活器
  6. java8默认垃圾回收器,Java 8的默认垃圾收集器
  7. [NOIP2005] 提高组 洛谷P1051 谁拿了最多奖学金
  8. eval() python_python的eval和exec的区别与联系
  9. 解决Kscope中文乱码问题
  10. 会计电算化是对用电子计算机处理,会计电算化的意义是什么
  11. Hive与RDBMS的区别
  12. Cocos2D-X笔记(1)制作一个动态的精灵
  13. 自组织映射 (SOM) 解决旅行商问题 (TSP)
  14. Tableau豆瓣电影数据项目实战练习1
  15. Mac的聚焦搜索Spotlight搜索不准确问题
  16. Window7开机速度有点慢的解决办法
  17. AutoMapper小结
  18. Libgdx介绍及环境安装
  19. 英国大不列颠百科全书_大不列颠计划通过社区编辑接受维基百科
  20. 天融信防火墙web配置_常见web系统默认口令总结

热门文章

  1. Android平台i2c-tools及16位地址读写,以及not executable: 64-bit ELF file解决办法
  2. python 通信_深入浅出通信原理(Python代码版)
  3. 六、3D数学矩阵线性变换
  4. SHA1算法原理(转载)
  5. openssl数据加密
  6. 汇编语言ADDC可以把C清零吗,常用汇编语言指令及解释
  7. 台式机XP系统调节屏幕亮度
  8. java 中uuid生成算法_UUID生成算法,UUID还是snowflake
  9. MAC地址生成器(可带跳数)
  10. UDP socket--sendto and recvfrom