ZooKeeper 实战(四) Curator Watch事件监听
文章目录
- ZooKeeper 实战(四) Curator Watch事件监听
- 0.前言
- 1.Watch 事件监听概念
- 2.NodeCache
- 2.1.全参构造器参数
- 2.2.代码DEMO
- 2.3.日志输出
- 3.PathChildrenCache
- 3.1.全参构造器参数
- 3.2.子节点监听时间类型
- 3.2.代码DEMO
- 4.TreeCache
- 4.1.构造器参数
- 4.2.代码DEMO
- 4.3.日志输出
ZooKeeper 实战(四) Curator Watch事件监听
0.前言
上一篇博客只介绍了有关Curator中对ZNode的CRUD操作,从本篇起开始逐步介绍更加高级的API操作。
1.Watch 事件监听概念
ZooKeeper 中引入了Watcher机制来实现了发布/订阅功能能,能够让多个订阅者同时监听某一个对象,当一个对象自身状态变化时,会通知所有订阅者。虽然ZooKeeper原生支持通过注册Watcher来进行事件监听,但是其使用并不是特别方便,需要开发人员反复注册Watcher,比较繁琐。
而 Curator 引入了Cache 来实现对 ZooKeeper 服务端事件的监听。
Curator 中提供了三种 Cache(Watcher)来监听不同节点变化类型:
- NodeCache:监听指定的节点。
- PathChildrenCache:监听指定节点的子节点。
- TreeCache:监听指定节点及其子孙节点。
2.NodeCache
监听指定的节点,增删改都会监听。
2.1.全参构造器参数
/*** @param: client 注册监听的客户端* @param: path 节点路径* @param: dataIsCompressed 是否开启数据压缩。传递的数据会进行压缩,传递速度快,但取数据时需要把压缩的数据进行转换,默认为false*/
public NodeCache(CuratorFramework client, String path, boolean dataIsCompressed);
2.2.代码DEMO
@Overridepublic void run(ApplicationArguments args) throws Exception {log.info("。。。。。。。。。。。。。容器初始化完毕。。。。。。。。。。。。。。");String path = "/ahao/watcher";TimeUnit.SECONDS.sleep(3);// 创建NodeCache对象NodeCache nodeCache = new NodeCache(client,path);// 添加监听器nodeCache.getListenable().addListener(new NodeCacheListener() {@Overridepublic void nodeChanged() throws Exception {ChildData currentData = nodeCache.getCurrentData();if (currentData != null){String s = new String(currentData.getData(),StandardCharsets.UTF_8);log.info("监听{}节点发生变化,数据内容:{}",path,s);}else {log.info("监听{}节点被删除了",path);}}});// 开启监听nodeCache.start();TimeUnit.SECONDS.sleep(2);// 创建节点client.create().creatingParentsIfNeeded().forPath(path,"第一次新增".getBytes(StandardCharsets.UTF_8));TimeUnit.SECONDS.sleep(2);// 更新节点client.setData().forPath(path,"数据修改了".getBytes(StandardCharsets.UTF_8));TimeUnit.SECONDS.sleep(2);// 删除节点client.delete().deletingChildrenIfNeeded().forPath(path);}
2.3.日志输出
3.PathChildrenCache
监听指定节点的子节点。当一个子节点增删改时, PathChildrenCache会包含最新的子节点的数据和状态。
3.1.全参构造器参数
/*** @param: client 注册监听的客户端* @param: path 节点路径* @param: cacheData 是否缓存节点内容(包含节点状态)* @param: dataIsCompressed 是否开启数据压缩。传递的数据会进行压缩,传递速度快,但取数据时需要把压缩的数据进行转换,默认为false* @param: executorService 用于PathChildrenCache的后台线程的线程池。该线程池应该是单线程的,否则缓存可能会看到不一致的结果*/
public PathChildrenCache(CuratorFramework client, String path, boolean cacheData, boolean dataIsCompressed, final CloseableExecutorService executorService)
3.2.子节点监听时间类型
public enum Type
{// 子节点添加CHILD_ADDED,// 子节点的数据变更CHILD_UPDATED,// 子节点被删除CHILD_REMOVED,// 以下三个事件类型表示:当连接断开时,PathChildrenCache将继续保持其断开连接之前的状态,并且在连接恢复后,PathChildrenCache将为断开连接期间发生的所有添加、删除和更新发出正常的子事件。// 当连接状态处于ConnectionState.SUSPENDED。CONNECTION_SUSPENDED,// 当连接状态处于ConnectionState.RECONNECTEDCONNECTION_RECONNECTED,// 当连接状态处于ConnectionState.LOSTCONNECTION_LOST,// 当通过PathChildrenCache.start(PathChildrenCache.StartMode.POST_INITIALIZED_EVENT)启动监听时,该事件表示PathChildrenCache初始化完成This event signals that the initial cache has been populated.INITIALIZED
}
3.2.代码DEMO
@Overridepublic void run(ApplicationArguments args) throws Exception {log.info("。。。。。。。。。。。。。容器初始化完毕。。。。。。。。。。。。。。");String path = "/ahao/watcher";TimeUnit.SECONDS.sleep(3);// 创建PathChildrenCache对象// 此处的cacheData参数一定要设置为true,不然Curator不会缓存数据当本地,// 那么后续pathChildrenCache.getCurrentData()得到的数据都为nullPathChildrenCache pathChildrenCache = new PathChildrenCache(client,path,true);// 添加监听器pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {@Overridepublic void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {if (event.getType() == PathChildrenCacheEvent.Type.INITIALIZED){log.info("PathChildrenCache初始化完,事件类型:{}", event.getType());}else {ChildData currentData = event.getData();log.info("事件类型:{},监听到的子节点发生变化:{}",event.getType(),currentData.getPath());}}});// 开启监听pathChildrenCache.start(PathChildrenCache.StartMode.POST_INITIALIZED_EVENT);// 创建子节点TimeUnit.SECONDS.sleep(2);client.create().creatingParentsIfNeeded().forPath(path+"/c1");client.create().creatingParentsIfNeeded().forPath(path+"/c2");client.create().creatingParentsIfNeeded().forPath(path+"/c3/age");// 修改子节点TimeUnit.SECONDS.sleep(2);client.setData().forPath(path+"/c1","c1更新了".getBytes(StandardCharsets.UTF_8));client.setData().forPath(path+"/c2","c2更新了".getBytes(StandardCharsets.UTF_8));// 删除子节点TimeUnit.SECONDS.sleep(2);client.delete().deletingChildrenIfNeeded().forPath(path+"/c3");}
3.3.日志输出
可以看出,PathChildrenCache只会监听直属子节点的变化,其非直属子节点的后代节点如/c3/age,没有发布通知。
4.TreeCache
监听指定节点及其子孙节点。
4.1.构造器参数
/*** @param: client 注册监听的客户端* @param: path 节点路径*/
public TreeCache(CuratorFramework client, String path)/*** @param: client 注册监听的客户端* @param: path 节点路径* @param: cacheData 是否缓存节点内容(包含节点状态)* @param: dataIsCompressed 是否开启数据压缩。传递的数据会进行压缩,传递速度快,但取数据时需要把压缩的数据进行转换,默认为false* @param: maxDepth 最大深度。最深的那个后代节点到path所需要经过的节点数* @param: executorService 用于PathChildrenCache的后台线程的线程池。该线程池应该是单线程的,否则缓存可能会看到不一致的结果* @param: createParentNodes 是否需要创建父节点。如果父节点不存在泽创建父节点(容器节点)* @param: TreeCacheSelector TreeCache选择器。根据指定的策略和条件,选择适合的缓存树来创建和维护TreeCache*/
TreeCache(CuratorFramework client, String path, boolean cacheData, boolean dataIsCompressed, int maxDepth, final ExecutorService executorService, boolean createParentNodes, TreeCacheSelector selector)
4.2.代码DEMO
@Overridepublic void run(ApplicationArguments args) throws Exception {log.info("。。。。。。。。。。。。。容器初始化完毕。。。。。。。。。。。。。。");String path = "/ahao/watcher/tree";TimeUnit.SECONDS.sleep(3);// 创建TreeCache对象,也可通过TreeCache.newBuilder()创建TreeCache treeCache = new TreeCache(client,path);treeCache.getListenable().addListener(new TreeCacheListener() {@Overridepublic void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {if (event.getType() == TreeCacheEvent.Type.INITIALIZED){log.info("TreeCache初始化完,事件类型:{}", event.getType());}else {ChildData currentData = event.getData();log.info("事件类型:{},监听到的子节点发生变化:{}",event.getType(),currentData.getPath());}}});// 开启监听treeCache.start();// 创建节点TimeUnit.SECONDS.sleep(2);client.create().creatingParentsIfNeeded().forPath(path);client.create().creatingParentsIfNeeded().forPath(path +"/t1");client.create().creatingParentsIfNeeded().forPath(path +"/t2/ccc");// 修改子节点TimeUnit.SECONDS.sleep(2);client.setData().forPath(path,"根节点更新了".getBytes(StandardCharsets.UTF_8));client.setData().forPath(path +"/t2/ccc","/t2/ccc更新了".getBytes(StandardCharsets.UTF_8));// 删除子节点TimeUnit.SECONDS.sleep(2);client.delete().deletingChildrenIfNeeded().forPath(path +"/t2");}
4.3.日志输出
可以看出TreeCache会监听当前节点和后代节点的变化。
相关文章:
ZooKeeper 实战(四) Curator Watch事件监听
文章目录 ZooKeeper 实战(四) Curator Watch事件监听0.前言1.Watch 事件监听概念2.NodeCache2.1.全参构造器参数2.2.代码DEMO2.3.日志输出 3.PathChildrenCache3.1.全参构造器参数3.2.子节点监听时间类型3.2.代码DEMO 4.TreeCache4.1.构造器参数4.2.代码DEMO4.3.日志输出 ZooKe…...
Spring Boot 构建工具插件
本文为官方文档直译版本。原文链接 Spring Boot 构建工具插件 引言Spring Boot Maven PluginSpring Boot Gradle PluginSpring Boot AntLib 模块Spring Boot Ant 任务使用 "exejar" 任务示例 使用 "findmainclass" 任务例子 支持其它构建系统重新包装档案嵌…...
Java集成消息队列Kafka
1.Kafka maven坐标 在使用Maven构建Java项目时,你可以通过添加Kafka的Maven依赖来引入Kafka相关的库。下面是Kafka的Maven坐标: <dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId&g…...
第十四章JSON
第十四章JSON 1.什么是JSON2.JSON的定义和访问3.JSON在JavaScript中两种常用的转换方式4.JavaBean和JSON的相互转换5.List集合和JSON的相互转换6.map集合和JSON的相互转换 1.什么是JSON 2.JSON的定义和访问 JSON的定义 JSON的类型是一个Object类型 JSON的访问 我们要…...
0_项目git地址——正点原子minifly与crazyflie
1、说明: 在每个专栏的第一篇文章,笔者都会贴出项目的git地址,方便后来者学习和复现; 下面介绍两个项目的官网资料和git地址,最后给出两者的对比; 2、正点原子minifly (1)minifly官网资料下载中心&#…...
php 字符串常用函数
目录 1.一些常用函数 2.代码示例 1.一些常用函数 函数名描述trim()删除字符串两端空行或其它预定义符rtrim()删除字符串右边空行或其它预定义符ltrim()删除字符串左边空行或其它预定义符dirname()返回路径中的目录部分str_split()把字符串分割到数组里explode()使用一个字符串…...
Android基于Matrix绘制PaintDrawable设置BitmapShader,以手指触点为中心显示原图像圆图,Kotlin(2)
Android基于Matrix绘制PaintDrawable设置BitmapShader,以手指触点为中心显示原图像圆图,Kotlin(2) 在 https://zhangphil.blog.csdn.net/article/details/135374279 基础上,增加一个功能,当手指在上面的图片…...
FlinkOnYarn 监控 flink任务
Flink任务一般为实时不断运行的任务,如果没有任务监控, 任务异常时无法第一时间处理会比较麻烦。 这里通过调用API接口方式来获取参数,实现任务监控。 Flink任务监控(基于API接口编写shell脚本) 一 flink-on-yarn 模式 二 编写she…...
C++内存管理机制(侯捷)笔记1
C内存管理机制(侯捷) 本文是学习笔记,仅供个人学习使用。如有侵权,请联系删除。 参考链接 Youtube: 侯捷-C内存管理机制 Github课程视频、PPT和源代码: https://github.com/ZachL1/Bilibili-plus 第一讲primitives的笔记 截至…...
【论文阅读】Non-blocking Lazy Schema Changes in Multi-Version
Non-blocking Lazy Schema Changes in Multi-Version Database Management Systems 1. Intro 1.1 Motivation 一个是online能够提供不停机的更新的能力,在很多业务系统里面是必要的。第二个是满足高可用,SaaS、PaaS要提供高可用的系统给用户ÿ…...
Rust 最新版1.75.0升级记
升级方法 稳定版 C:\>rustup update stable info: syncing channel updates for stable-x86_64-pc-windows-msvc info: latest update on 2023-12-28, rust version 1.75.0 (82e1608df 2023-12-21) info: downloading component cargo 5.9 MiB / 5.9 MiB (100 %) 3.…...
使用 KubeSphere 与极狐GitLab 打造云原生持续交付系统
极狐GitLab 简介 极狐GitLab 是一个一体化的 DevOps 平台,可以简单理解为 GitLab 在国内的“发行版”。是由极狐(GitLab)公司推出的产品(极狐(GitLab)公司是以“中外合资3.0”模式成立的公司,在国内独立运营,为国内用户提供适合本…...
EasyExcel的追加写入(新增POI、CSV)
总结:目前市面上流行的2种 EasyExcel和POI都不是真正的对物理excel文件进行追加导入。只是在缓存里面追加,最后一次性写入,并不能解决内存占用问题。 1.EasyExcel2.POI3.CSV 无非就是下面两种逻辑: 1.for循环查询数据,…...
JetBrains 开发工具——免费教育许可申请流程
JetBrains 开发工具——免费教育许可申请流程 本文将详细介绍通过教育邮箱申请Free Educational Licenses. Free Educational Licenses地址 1.选择符合自己的申请入口 2.填写申请表单提交 官方指南 😃😃😃...
打造高性价比小程序,轻松降低成本
随着移动互联网的普及,小程序已经成为一个热门的应用开发方向。然而,对于许多企业和个人而言,制作一个小程序的费用却让人望而却步。那么,如何以最低的成本制作一款高性价比的小程序呢? 答案很简单,只需要找…...
mysql 索引优化查询
MySQL的索引可以提高数据库查询性能。下面是一些常用的MySQL索引优化技巧: 创建合适的索引:根据查询条件选择合适的列作为索引,并确保这些索引在WHERE子句中被使用到。 示例代码:CREATE INDEX idx_name ON table_name (column_nam…...
跟着cherno手搓游戏引擎【4】窗口抽象、GLFW配置
引入GLFW: 在vendor里创建GLFW文件夹: 在github上下载,把包下载到GLFW包下。 GitHub - TheCherno/glfw: A multi-platform library for OpenGL, OpenGL ES, Vulkan, window and input修改SRC/premake5.lua的配置:12、13、15、36…...
Tomcat基础升华学习
01 What is Tomcat 1.1 Tomcat官网 官网 :https://tomcat.apache.org 1.2 Understand 为什么说Tomcat是Servlet之类技术的实现? 在我们的理解中,Tomcat可以称为Web容器或者Servlet容器 不妨通过手写一个Tomcat来推导一下 1.2.1 创建Tomc…...
一种具有轨迹优化的无人驾驶车实时运动规划器 论文阅读
论文题目:A Real-Time Motion Planner with Trajectory Optimization for Autonomous Vehicles Abstract 本文的实时规划器首先将空间离散化,然后基于一组成本函数搜索出最佳轨迹。迭代优化所得到的轨迹的Path和Speed。post-optimization计算复杂度低&…...
GPDB - 高可用 - 流复制状态
GPDB - 高可用 - 流复制状态 GPDB的高可用基于流复制,通过FTS进行自动故障切换。自动故障切换需要根据primary-mirror流复制的各种状态进行判断。本节就聊聊primary-mirror流复制的各种状态。同样适用于PgSQL 1、WalSndState typedef enum WalSndState {WALSNDSTATE…...
最佳解决方案:如何在网络爬虫中解决验证码
Captcha(全自动区分计算机和人类的公开图灵测试)是广泛应用的安全措施,用于区分合法的人类用户和自动化机器人。它通过呈现复杂的挑战,包括视觉上扭曲的文本、复杂的图像或复杂的拼图等方式,要求用户成功解决这些挑战以…...
在线项目实习分享:股票价格形态聚类与收益分析
01前置课程 数据挖掘基础数据探索数据预处理数据挖掘算法基础Python数据挖掘编程基础Matplotlib可视化Pyecharts绘图 02师傅带练 行业联动与轮动分析 通过分析申银万国行业交易指数的联动与轮动现象,获得有意义的行业轮动关联规则,并在此基础上设计量…...
c# vb.net检测字符串是否匹配一组相似度数组input Like
VB.NET 检测字符串是否符合一个数组中的多个like条件,有没有最简单的函数? 在VB.NET中,可以使用Array.Exists方法结合String.Like方法来检测一个字符串是否符合一个数组中的多个LIKE条件。Array.Exists方法用于确定序列中的任何元素是否满足…...
DEJA_VU3D - Cesium功能集 之 113-获取圆节点(2)
前言 编写这个专栏主要目的是对工作之中基于Cesium实现过的功能进行整合,有自己琢磨实现的,也有参考其他大神后整理实现的,初步算了算现在有差不多实现小140个左右的功能,后续也会不断的追加,所以暂时打算一周2-3更的样子来更新本专栏(每篇博文都会奉上完整demo的源代码…...
spring-boot项目启动类错误: 找不到或无法加载主类 com.**Application
问题:Springboot项目启动报错:错误: 找不到或无法加载主类 com.**Application 解决步骤: 1.File–>Project Structure 2.Modules–>选中你的项目–点击“-”移除 3.重新导入:点击“”号,选择Import Module&…...
搭建大数据开发环境【AutoDL容器】
租用AutoDL容器 注意:结束实验时记得将数据库数据转移存储 使用Docker实现本地IDEA连接AutoDL 后为ssh服务器地址用户名为前的端口号ssh密码为用户密码 安装JDK 压缩包安装 Java下载地址:Oracle Java Download(hadoop不指定特定版本java&…...
写一个简单的Java的Gui文本输入窗口,JFrame的简单使用
JFrame是指一个计算机语言-java的GUI程序的基本思路是以JFrame为基础,它是屏幕上window的对象,能够最大化、最小化、关闭。 Swing的三个基本构造块:标签、按钮和文本字段;但是需要个地方安放它们,并希望用户知道如何处理它们。JFrame 类就是解决这个问题的——它是一个容器…...
Unity中URP下抓屏的 开启 和 使用
文章目录 前言一、抓屏开启1、Unity下开启抓屏2、Shader中开启抓屏 二、抓屏使用1、设置为半透明渲染队列,关闭深度写入2、申明纹理和采样器3、在片元着色器使用请添加图片描述 三、测试代码 前言 我们在这篇文章中看一下,URP下怎么开启抓屏。 一、抓屏…...
业务题day01
1-1 请说一下你项目中是如何进行项目管理和发布的 我们项目使用的是Gogs进行代码托管,Jenkins进行项目自动运维发布。 在我们的项目中,我们使用Gogs进行代码托管和版本控制,以确保团队成员可以协同开发和管理代码。 Gogs是一个轻量级的、开…...
DEJA_VU3D - Cesium功能集 之 114-雷达效果(基础效果)
前言 编写这个专栏主要目的是对工作之中基于Cesium实现过的功能进行整合,有自己琢磨实现的,也有参考其他大神后整理实现的,初步算了算现在有差不多实现小140个左右的功能,后续也会不断的追加,所以暂时打算一周2-3更的样子来更新本专栏(每篇博文都会奉上完整demo的源代码…...
创意二维码制作网站/营销平台是什么意思
点击上方“Java基基”,选择“设为星标”做积极的人,而不是积极废人!每天 14:00 更新文章,每天掉亿点点头发...源码精品专栏 原创 | Java 2021 超神之路,很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应用框…...
广州网站建设制作价格/西安做网页的公司
ember 动态切换组件本文由Edwin Reynoso和Nilson Jacques进行了同行评审。 感谢所有SitePoint的同行评审员使SitePoint内容达到最佳状态! 组件是Ember应用程序的重要组成部分。 它们允许您定义自己的,特定于应用程序HTML标记,并使用JavaScri…...
网站备案期间可以做推广吗/洛阳网站建设
推荐书目详细介绍,请参阅文件:充电书库-Q4第一期推荐书目.xlsx 序号 书名 作者 序号 书名 作者 1原则[美] 瑞达利欧;2当下的力量埃克哈特•托利 (Eckhart Tolle);3创业维艰:如何完成比难更难的事本霍洛维茨4心理学…...
汕头网站外包/关键词歌曲
转载于:https://www.cnblogs.com/xiaochi/p/11532711.html...
利用php做网站教程/百度搜索关键词规则
一、Synchronized的基本使用 Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法。Synchronized的作用主要有三个:(1)确保线程互斥的访问同步代码(2)保证共享变量的修改能够及时可见…...
常州便宜的做网站服务/外链工具xg
Python 爬虫模拟登录 Python 爬虫模拟登录是使用脚本实现自动登录,部分站点需要逆向加密逻辑,更多的站点会采用验证码进行鉴权验证。 本文为大家带来最简单的登录,其核心用到的是 requests 模拟 POST 请求。 本次练习使用的站点是 https:/…...