当前位置:   article > 正文

11.0 Zookeeper watcher 事件机制原理剖析

11.0 Zookeeper watcher 事件机制原理剖析

zookeeper 的 watcher 机制,可以分为四个过程:

  • 客户端注册 watcher。
  • 服务端处理 watcher。
  • 服务端触发 watcher 事件。
  • 客户端回调 watcher。

其中客户端注册 watcher 有三种方式,调用客户端 API 可以分别通过 getData、exists、getChildren 实现,利用前面章节创建的 maven 工程,新建 WatcherDemo 类,以 exists 方法举例说明其原理。

  1. // 导入 ZooKeeper 相关的类
  2. import org.apache.zookeeper.WatchedEvent;
  3. import org.apache.zookeeper.Watcher;
  4. import org.apache.zookeeper.ZooKeeper;
  5. import org.apache.zookeeper.KeeperException;
  6. import org.apache.zookeeper.data.Stat;
  7. // 定义 WatcherDemo 类,实现 Watcher 接口
  8. public class WatcherDemo implements Watcher {
  9. // 静态 ZooKeeper 客户端
  10. static ZooKeeper zooKeeper;
  11. // 静态代码块,初始化 ZooKeeper 客户端
  12. static {
  13. try {
  14. // 创建 ZooKeeper 客户端实例,连接到 ZooKeeper 服务器
  15. zooKeeper = new ZooKeeper("192.168.3.39:2181", 4000, new WatcherDemo());
  16. } catch (IOException e) {
  17. e.printStackTrace();
  18. }
  19. }
  20. // 重写 Watcher 接口的 process 方法,处理 ZooKeeper 事件
  21. @Override
  22. public void process(WatchedEvent event) {
  23. // 打印事件类型
  24. System.out.println("eventType:" + event.getType());
  25. // 判断事件类型
  26. if (event.getType() == Event.EventType.NodeDataChanged) {
  27. // 节点数据改变事件
  28. try {
  29. // 重新注册对节点的监视
  30. zooKeeper.exists(event.getPath(), true);
  31. } catch (KeeperException e) {
  32. e.printStackTrace();
  33. } catch (InterruptedException e) {
  34. e.printStackTrace();
  35. }
  36. }
  37. }
  38. // main 方法,程序入口
  39. public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
  40. // 定义节点路径
  41. String path = "/watcher";
  42. // 判断节点是否存在
  43. if (zooKeeper.exists(path, false) == null) {
  44. // 创建节点,并设置初始数据
  45. zooKeeper.create(path, "0".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
  46. }
  47. // 睡眠 1 秒
  48. Thread.sleep(1000);
  49. // 打印分割线
  50. System.out.println("-----------");
  51. // 重新注册对节点的监视,并设置 Watcher
  52. Stat stat = zooKeeper.exists(path, true);
  53. // 等待用户输入
  54. System.in.read();
  55. }
  56. }

运行完程序,控制台显示:

此时启动 zookeeper 命令行终端,查看并且删除 watcher 节点:

IDE 控制台输出,触发了节点删除事件:

客户端发送请求给服务端是通过 TCP 长连接建立网络通道,底层默认是通过 java 的 NIO 方式,也可以配置 netty 实现方式。

注册 watcher 监听事件流程图:

1、客户端发送事件通知请求

在 Zookeeper 类调用 exists 方法时候,把创建事件监听封装到 request 对象中,watch 属性设置为 true,待服务端返回 response 后把监听事件封装到客户端的 ZKWatchManager 类中。

2、服务端处理 watcher 事件的请求

服务端 NIOServerCnxn 类用来处理客户端发送过来的请求,最终调用到 FinalRequestProcessor,其中有一段源码添加客户端发送过来的 watcher 事件:

然后进入 statNode 方法,在 DataTree 类方法中添加 watcher 事件,并保存至 WatchManager 的 watchTable 与 watchTable 中。

3、服务端触发 watcher 事件流程:

若服务端某个被监听的节点发生事务请求,服务端处理请求过程中调用 FinalRequestProcessor 类 processRequest 方法中的代码如下所示:

删除调用链最终到 DataTree 类中删除节点分支的触发代码段:

进入 WatchManager 类的 triggerWatch 方法:

继续跟踪进入 NIOServerCnxn,构建了一个 xid 为 -1,zxid 为 -1 的 ReplyHeader 对象,然后再调用 sendResonpe 方法。

4、客户端回调 watcher 事件

客户端 SendThread 类 readResponse 方法接收服务端触发的事件通知,进入 xid 为 -1 流程,处理 Event 事件。

希望你也学会了,更多编程源码模板请来二当家的素材网:https://www.erdangjiade.com

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
  • vhost:每个RabbitMQ都能创建很多vhost,我们称之为虚拟主机,每个虚拟主机其实都是mini版的RabbitMQ,它拥有自己的队列,交换器和绑定,拥有自己的权限机制,主要是为了隔离,vhost不仅消除了为基础架构中的每一层运行一... [详细]

  • 传统的单体框架,已经不满足目前公司战略规划要求,近几年“微服务“这个字眼,出现的越来越频繁,虽然有过一年多微服务项目经验,也很难把微服务解释清楚,到底何为微服务?哈哈哈,好正经的开头,MartinFowler曾在其blog上发表了”Micr... [详细]

  • 所需准备工作,创建三台虚拟机环境并安装好java开发工具包JDK,可以使用VM或者vagrant+virtualbox搭建centos/ubuntu环境,本案例基于宿主机windows10系统同时使用vagrant+virtualbox搭建... [详细]

  • 本章节介绍一下zookeeper的节点特性和简单使用场景,正是由于这些节点特性的存在使zookeeper开发出不同的场景应用。9.0Zookeeper节点特性本章节介绍一下zookeeper的节点特性和简单使用场景,正是由于这些节点特性的存... [详细]

  • zookeeper支持某些特定的四字命令与其交互,用户获取zookeeper服务的当前状态及相关信息,用户在客户端可以通过telenet或者nc(netcat)向zookeeper提交相应的命令。8.0Zookeeper四字命令教程详解zo... [详细]

  • 本教程使用的IDE为IntelliJIDEA,创建一个maven工程,命名为zookeeper-demo,并且引入如下依赖,可以自行在maven中央仓库选择合适的版本,介绍原生API和Curator两种方式。4.0ZookeeperJava... [详细]

  • ZooKeeper是Apache软件基金会的一个软件项目,它为大型分布式计算提供开源的分布式配置服务、同步服务和命名注册。ZooKeeper的架构通过冗余服务实现高可用性。Zookeeper的设计目标是将那些复杂且容易出错的分布式一致性服务... [详细]

  • 修改zoo.cfg配置文件,将dataDir=/tmp/zookeeper修改成zookeeper安装目录所在的data文件夹,再添加一条添加数据日志的配置(需要根据自己的安装路径修改)。选择一稳定版本,本教程使用的release版本为3.... [详细]

  • 即使正确实现了这些服务,当应用程序部署时,这些服务的不同实现也会导致管理上的复杂性。由于实现这些服务的难度很大,应用程序通常会在这方面偷工减料,这使得它们在发生变更。每次实现这些服务时,都需要做大量的工作来修复不可避免的错误和竞态条件。所有... [详细]

相关标签
  

闽ICP备14008679号