ZooKeeper监听器原理

news/2024/9/24 2:49:52/

ZooKeeper监听器原理

ZooKeeper 监听器(Watcher)是 ZooKeeper 提供的一种机制,用于实现分布式系统中的事件通知

1.流程

  1. 注册监听器
  • 客户端在与 ZooKeeper 服务器建立连接后,可以通过某些操作(例如获取节点数据、检查节点是否存在等)注册一个 Watcher 对象,来监视特定节点的状态变化。
  1. 事件通知
  • 当某个与客户端关联的节点状态发生变化(例如节点被创建、数据被修改、节点被删除等),ZooKeeper 服务器会将相应的事件通知发送给客户端。
  1. 事件队列
  • ZooKeeper 客户端维护一个事件队列,用于存储接收到的事件通知
  • 当事件通知到达客户端时,会被放入事件队列中等待处理。
  1. 回调处理
  • 客户端在注册监听器时,通常会提供一个回调函数(或者说是回调方法)
  • 当事件通知被放入事件队列后,客户端会从事件队列中取出通知,并执行相应的回调函数来处理事件。
  1. 重新注册监听器
  • 一旦监听器收到了事件通知并处理完毕,客户端通常会选择重新注册监听器,以便继续监视节点的状态变化。这样就能保持持续的事件监听。
  1. 临时性
  • 监听器是一次性的,即一旦触发了事件通知,该监听器就会被移除
  • 因此,客户端需要在处理完事件后重新注册监听器,以确保持续地监视节点状态的变化。

在这里插入图片描述

通过这种机制,ZooKeeper 可以实现分布式系统中的事件驱动模型,使得客户端能够实时地获取和响应节点状态的变化,从而实现更加灵活和可靠的分布式协作。


2.示例

本示例创建了一个 ZooKeeperWatcherExample 类,其中使用了 ZooKeeper 的 Java 客户端 API 来连接 ZooKeeper 服务器、创建节点、设置节点数据,并注册了节点监听器。当节点的数据发生变化时,监听器会被触发,从而执行相应的回调方法,重新获取节点数据并打印出来。

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;public class ZooKeeperWatcherExample implements Watcher {// ZooKeeper 服务器地址private static final String ZOOKEEPER_ADDRESS = "localhost:2181";// 会话超时时间private static final int SESSION_TIMEOUT = 3000;// 节点路径private static final String NODE_PATH = "/example";// ZooKeeper 客户端private ZooKeeper zooKeeper;// 构造方法,在初始化时连接 ZooKeeper 服务器public ZooKeeperWatcherExample() {try {// 连接 ZooKeeper 服务器this.zooKeeper = new ZooKeeper(ZOOKEEPER_ADDRESS, SESSION_TIMEOUT, this);} catch (Exception e) {e.printStackTrace();}}// Watcher 接口的回调方法,处理节点状态变化事件@Overridepublic void process(WatchedEvent event) {// 节点状态变化事件if (event.getType() == Event.EventType.NodeDataChanged ||event.getType() == Event.EventType.NodeCreated ||event.getType() == Event.EventType.NodeDeleted) {// 重新获取节点数据,并注册监听器getNodeData();}}// 获取节点数据,并注册监听器private void getNodeData() {try {// 获取节点数据和状态信息Stat stat = new Stat();byte[] data = zooKeeper.getData(NODE_PATH, this, stat);String nodeData = new String(data);System.out.println("Node data: " + nodeData);// 注册监听器zooKeeper.exists(NODE_PATH, this);} catch (Exception e) {e.printStackTrace();}}// 设置节点数据public void setNodeData(String data) {try {// 检查节点是否存在Stat stat = zooKeeper.exists(NODE_PATH, false);if (stat != null) {// 设置节点数据zooKeeper.setData(NODE_PATH, data.getBytes(), stat.getVersion());} else {System.out.println("Node doesn't exist");}} catch (Exception e) {e.printStackTrace();}}// 主方法,用于演示public static void main(String[] args) throws InterruptedException {// 创建示例对象ZooKeeperWatcherExample example = new ZooKeeperWatcherExample();// 创建示例节点try {example.zooKeeper.create(NODE_PATH, "Initial data".getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);} catch (Exception e) {e.printStackTrace();}// 设置节点数据example.setNodeData("Updated data");// 等待一段时间,观察节点状态变化Thread.sleep(5000);// 关闭 ZooKeeper 连接try {example.zooKeeper.close();} catch (Exception e) {e.printStackTrace();}}
}

http://www.ppmy.cn/news/1429136.html

相关文章

lua整合redis

文章目录 lua基础只适合lua连接操作redis1.下载lua依赖2.导包,连接3.常用的命令1.set,get,push命令 2.自增管道命令命令集合4.使用redis操作lua1.实现秒杀功能synchronized关键字 分布式锁 lua 基础只适合 1.编译 -- 编译 luac a.lua -- 运行 lua a.lua2.命名规范 -- 多行注…

数据结构--双向链表

在讲双向链表之前,我们先了解一下链表的分类: 链表的结构⾮常多样,主要分为带头与不带头、单向与双向、循环与不循环。三个种类可以任意搭配,所以总共可以形成八种链表,但是最常用的是单向不带头不循环链表和双向带头循…

设计模式- 代理模式(Proxy Pattern)结构|原理|优缺点|场景|示例

目录 设计模式(分类) 设计模式(六大原则) 创建型 工厂方法 抽象工厂模式 单例模式 建造者模式 原型模式 结构型 适配器模式 装饰器模式 代理模式 代理模式(Prox…

常用渗透测试checklist

该渗透测试checklist包含以下几个模块: 测试大类、测试项、威胁等级、漏洞描述、修复方案 一、认证与授权类 1.密码明文传输 威胁等级:低危 漏洞描述:密码明文传输一般存在于web网站登录页面,用户名或者密码采用了明文传输&am…

二叉树相关

二叉树相关 力扣104 二叉树最大深度 普通递归遍历力扣 104 递归遍历2二叉树求前序遍历结果二叉树求 每个节点所在层数与每个节点的左右子树上的节点总数力扣 543 二叉树的直径 力扣104 二叉树最大深度 普通递归遍历 int depth 0;int maxDepth 0;public int maxDepth(TreeNod…

Day08React——第八天

useEffect 概念:useEffect 是一个 React Hook 函数,用于在React组件中创建不是由事件引起而是由渲染本身引起的操作,比如发送AJAx请求,更改daom等等 需求:在组件渲染完毕后,立刻从服务器获取频道列表数据…

机器学习(二)之监督学习

前言: 上一节大概讲解了几种学习方式,下面几张就具体来讲讲监督学习的几种算法。 以下示例中和都是权重的意思!!! 注:本文如有错误之处,还请读者指出,欢迎评论区探讨! 1…

学习 Rust 的第六天:所有权问题

大家好, 欢迎来到学习 Rust 的第 6 天,过去 5 天我们学到的内容在几乎每种语言中都是一样的。所有权是 Rust 的一个独特概念。 介绍 所有权是一种独特的内存管理系统,其中每个值都有一个指定的所有者,在所有者超出范围时自动释…