Zookeeper - 基于 Java API 的客户端连接实操开发
大家好欢迎来到我的技术博客 在这里我会分享学习笔记、实战经验与技术思考力求用简单的方式讲清楚复杂的问题。 本文将围绕Zookeeper这个话题展开希望能为你带来一些启发或实用的参考。 无论你是刚入门的新手还是正在进阶的开发者希望你都能有所收获文章目录Zookeeper - 基于 Java API 的客户端连接实操开发 引言环境准备 创建 Maven 项目可选建立 Zookeeper 客户端连接 示例代码代码说明创建节点 示例代码代码说明获取节点数据 示例代码代码说明更新节点数据 示例代码代码说明删除节点 ️示例代码代码说明节点监听机制 示例代码代码说明Zookeeper 客户端连接状态管理 示例代码代码说明使用 Curator 框架简化开发 示例代码使用 Curator代码说明总结 Zookeeper - 基于 Java API 的客户端连接实操开发 引言Apache Zookeeper 是一个分布式协调服务广泛用于分布式系统的协调与管理。它提供了诸如命名服务、分布式同步、集群管理等功能是构建高可用、可扩展的分布式系统的重要工具之一。在实际开发中Zookeeper 的 Java API 是开发者最常用的接口之一。本文将详细介绍如何使用 Java API 实现 Zookeeper 客户端的连接、节点操作、监听机制等核心功能并通过代码示例帮助读者更好地理解和实践。环境准备 在开始之前我们需要准备好以下环境Java 8 或更高版本Zookeeper 3.5 或更高版本IDE如 IntelliJ IDEA 或 EclipseMaven 项目可选你可以从 Zookeeper 官方网站 下载并安装 Zookeeper。安装完成后确保 Zookeeper 服务已经启动。创建 Maven 项目可选如果你使用 Maven 来管理项目依赖可以在pom.xml文件中添加以下依赖项dependenciesdependencygroupIdorg.apache.zookeeper/groupIdartifactIdzookeeper/artifactIdversion3.7.1/version/dependency/dependencies⚠️ 注意请根据你使用的 Zookeeper 版本选择合适的依赖版本。建立 Zookeeper 客户端连接 Zookeeper 客户端的连接是通过ZooKeeper类来实现的。我们可以通过构造函数创建一个客户端实例并连接到 Zookeeper 服务器。示例代码importorg.apache.zookeeper.WatchedEvent;importorg.apache.zookeeper.Watcher;importorg.apache.zookeeper.ZooKeeper;importjava.io.IOException;publicclassZookeeperClientExample{publicstaticvoidmain(String[]args){StringhostPortlocalhost:2181;// Zookeeper 服务器地址intsessionTimeout3000;// 会话超时时间try{ZooKeeperzooKeepernewZooKeeper(hostPort,sessionTimeout,newWatcher(){Overridepublicvoidprocess(WatchedEventevent){// 监听事件回调System.out.println(Received event: event.getType());}});System.out.println(Connected to Zookeeper server);// 阻止主线程退出保持连接Thread.sleep(Long.MAX_VALUE);zooKeeper.close();}catch(IOException|InterruptedExceptione){e.printStackTrace();}}}代码说明ZooKeeper构造函数的参数说明hostPortZookeeper 服务器地址格式为host:port。sessionTimeout会话超时时间单位为毫秒。watcher监听器用于监听 Zookeeper 事件。process方法是Watcher接口的实现用于处理 Zookeeper 事件。Thread.sleep(Long.MAX_VALUE)用于保持主线程不退出从而保持与 Zookeeper 的连接。创建节点 在 Zookeeper 中节点ZNode是数据存储的基本单位。我们可以通过create方法创建节点。示例代码importorg.apache.zookeeper.CreateMode;importorg.apache.zookeeper.ZooDefs;importorg.apache.zookeeper.ZooKeeper;importorg.apache.zookeeper.data.Stat;importjava.io.IOException;importjava.util.concurrent.CountDownLatch;publicclassCreateZNodeExample{publicstaticvoidmain(String[]args)throwsIOException,InterruptedException{StringhostPortlocalhost:2181;intsessionTimeout3000;CountDownLatchconnectedSignalnewCountDownLatch(1);ZooKeeperzooKeepernewZooKeeper(hostPort,sessionTimeout,event-{if(event.getState()Event.KeeperState.SyncConnected){connectedSignal.countDown();}});connectedSignal.await();Stringpath/exampleNode;byte[]dataHello Zookeeper.getBytes();// 创建持久节点StringcreatedPathzooKeeper.create(path,data,ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);System.out.println(Created node at path: createdPath);zooKeeper.close();}}代码说明CreateMode.PERSISTENT创建一个持久节点。ZooDefs.Ids.OPEN_ACL_UNSAFE设置节点的 ACL访问控制列表这里使用的是开放权限。create方法返回新创建节点的路径。获取节点数据 我们可以使用getData方法获取节点的数据。示例代码importorg.apache.zookeeper.ZooKeeper;importorg.apache.zookeeper.data.Stat;importjava.io.IOException;importjava.util.concurrent.CountDownLatch;publicclassGetZNodeDataExample{publicstaticvoidmain(String[]args)throwsIOException,InterruptedException{StringhostPortlocalhost:2181;intsessionTimeout3000;CountDownLatchconnectedSignalnewCountDownLatch(1);ZooKeeperzooKeepernewZooKeeper(hostPort,sessionTimeout,event-{if(event.getState()Event.KeeperState.SyncConnected){connectedSignal.countDown();}});connectedSignal.await();Stringpath/exampleNode;StatstatnewStat();byte[]datazooKeeper.getData(path,false,stat);System.out.println(Node data: newString(data));zooKeeper.close();}}代码说明getData方法的参数说明path节点路径。watch是否设置监听器。stat用于存储节点的元数据。更新节点数据 我们可以使用setData方法更新节点的数据。示例代码importorg.apache.zookeeper.ZooKeeper;importorg.apache.zookeeper.data.Stat;importjava.io.IOException;importjava.util.concurrent.CountDownLatch;publicclassUpdateZNodeDataExample{publicstaticvoidmain(String[]args)throwsIOException,InterruptedException{StringhostPortlocalhost:2181;intsessionTimeout3000;CountDownLatchconnectedSignalnewCountDownLatch(1);ZooKeeperzooKeepernewZooKeeper(hostPort,sessionTimeout,event-{if(event.getState()Event.KeeperState.SyncConnected){connectedSignal.countDown();}});connectedSignal.await();Stringpath/exampleNode;byte[]newDataUpdated Data.getBytes();// 更新节点数据StatstatzooKeeper.setData(path,newData,-1);// -1 表示忽略版本号System.out.println(Node updated with version: stat.getVersion());zooKeeper.close();}}代码说明setData方法的参数说明path节点路径。data新的数据。version节点的版本号-1 表示忽略版本号。删除节点 ️我们可以使用delete方法删除节点。示例代码importorg.apache.zookeeper.ZooKeeper;importorg.apache.zookeeper.KeeperException;importjava.io.IOException;importjava.util.concurrent.CountDownLatch;publicclassDeleteZNodeExample{publicstaticvoidmain(String[]args)throwsIOException,InterruptedException,KeeperException{StringhostPortlocalhost:2181;intsessionTimeout3000;CountDownLatchconnectedSignalnewCountDownLatch(1);ZooKeeperzooKeepernewZooKeeper(hostPort,sessionTimeout,event-{if(event.getState()Event.KeeperState.SyncConnected){connectedSignal.countDown();}});connectedSignal.await();Stringpath/exampleNode;// 删除节点zooKeeper.delete(path,-1);// -1 表示忽略版本号System.out.println(Node deleted);zooKeeper.close();}}代码说明delete方法的参数说明path节点路径。version节点的版本号-1 表示忽略版本号。节点监听机制 Zookeeper 提供了强大的监听机制允许客户端监听节点的变化。我们可以通过exists、getData、getChildren等方法设置监听器。示例代码importorg.apache.zookeeper.WatchedEvent;importorg.apache.zookeeper.Watcher;importorg.apache.zookeeper.ZooKeeper;importorg.apache.zookeeper.data.Stat;importjava.io.IOException;importjava.util.concurrent.CountDownLatch;publicclassWatcherExample{publicstaticvoidmain(String[]args)throwsIOException,InterruptedException{StringhostPortlocalhost:2181;intsessionTimeout3000;CountDownLatchconnectedSignalnewCountDownLatch(1);ZooKeeperzooKeepernewZooKeeper(hostPort,sessionTimeout,newWatcher(){Overridepublicvoidprocess(WatchedEventevent){System.out.println(Received event: event.getType());if(event.getType()Event.EventType.Noneevent.getState()Event.KeeperState.SyncConnected){connectedSignal.countDown();}elseif(event.getType()Event.EventType.NodeDataChanged){System.out.println(Node data changed);}}});connectedSignal.await();Stringpath/exampleNode;// 设置监听器StatstatzooKeeper.exists(path,true);if(stat!null){System.out.println(Node exists);}else{System.out.println(Node does not exist);}// 阻止主线程退出保持连接Thread.sleep(Long.MAX_VALUE);zooKeeper.close();}}代码说明exists方法的参数说明path节点路径。watch是否设置监听器。当节点数据发生变化时监听器会收到NodeDataChanged事件。Zookeeper 客户端连接状态管理 在实际应用中Zookeeper 客户端可能会因为网络问题或服务器故障而断开连接。我们需要处理这些情况并实现自动重连机制。示例代码importorg.apache.zookeeper.WatchedEvent;importorg.apache.zookeeper.Watcher;importorg.apache.zookeeper.ZooKeeper;importorg.apache.zookeeper.KeeperException;importjava.io.IOException;importjava.util.concurrent.CountDownLatch;publicclassReconnectExample{privatestaticZooKeeperzooKeeper;publicstaticvoidmain(String[]args){StringhostPortlocalhost:2181;intsessionTimeout3000;connectToZookeeper(hostPort,sessionTimeout);// 模拟断开连接try{Thread.sleep(5000);System.out.println(Simulating connection loss...);zooKeeper.close();Thread.sleep(5000);connectToZookeeper(hostPort,sessionTimeout);}catch(InterruptedException|IOExceptione){e.printStackTrace();}}privatestaticvoidconnectToZookeeper(StringhostPort,intsessionTimeout){CountDownLatchconnectedSignalnewCountDownLatch(1);try{zooKeepernewZooKeeper(hostPort,sessionTimeout,event-{if(event.getState()Watcher.Event.KeeperState.SyncConnected){connectedSignal.countDown();}elseif(event.getState()Watcher.Event.KeeperState.Disconnected){System.out.println(Disconnected from Zookeeper);}elseif(event.getState()Watcher.Event.KeeperState.Expired){System.out.println(Session expired);try{connectToZookeeper(hostPort,sessionTimeout);}catch(IOException|InterruptedExceptione){e.printStackTrace();}}});connectedSignal.await();System.out.println(Connected to Zookeeper);}catch(IOException|InterruptedExceptione){e.printStackTrace();}}}代码说明当客户端断开连接或会话过期时监听器会收到相应的事件。在会话过期的情况下我们尝试重新连接到 Zookeeper 服务器。使用 Curator 框架简化开发 虽然 Zookeeper 提供了原生的 Java API但在实际开发中我们通常会使用 Curator 框架来简化开发。Curator 是 Apache 提供的一个 Zookeeper 客户端框架它封装了原生 API并提供了更高级的功能。示例代码使用 Curatorimportorg.apache.curator.framework.CuratorFramework;importorg.apache.curator.framework.CuratorFrameworkFactory;importorg.apache.curator.retry.ExponentialBackoffRetry;publicclassCuratorExample{publicstaticvoidmain(String[]args)throwsException{StringhostPortlocalhost:2181;// 创建 Curator 客户端CuratorFrameworkclientCuratorFrameworkFactory.newClient(hostPort,newExponentialBackoffRetry(1000,3));client.start();Stringpath/curatorNode;byte[]dataHello Curator.getBytes();// 创建节点client.create().forPath(path,data);System.out.println(Node created);// 获取节点数据byte[]retrievedDataclient.getData().forPath(path);System.out.println(Node data: newString(retrievedData));// 更新节点数据byte[]newDataUpdated with Curator.getBytes();client.setData().forPath(path,newData);System.out.println(Node updated);// 删除节点client.delete().forPath(path);System.out.println(Node deleted);client.close();}}代码说明CuratorFrameworkFactory.newClient创建 Curator 客户端。ExponentialBackoffRetry设置重试策略。create()、getData()、setData()、delete()Curator 提供的简化 API。总结 通过本文的学习我们了解了如何使用 Zookeeper 的 Java API 实现客户端连接、节点操作、监听机制等功能。我们还介绍了如何使用 Curator 框架简化开发并提供了相应的代码示例。希望本文能帮助读者更好地理解和实践 Zookeeper 的 Java 客户端开发。如果你对 Zookeeper 感兴趣可以进一步阅读 Zookeeper 官方文档了解更多高级功能和最佳实践。同时Curator 官方文档 也是学习 Curator 框架的好资源。Happy coding! 感谢你读到这里 技术之路没有捷径但每一次阅读、思考和实践都在悄悄拉近你与目标的距离。 如果本文对你有帮助不妨 点赞、收藏、分享给更多需要的朋友 欢迎在评论区留下你的想法、疑问或建议我会一一回复我们一起交流、共同成长 关注我不错过下一篇干货我们下期再见✨

相关新闻

C++ vector O(1)删除技巧:交换-弹出法原理与实战

C++ vector O(1)删除技巧:交换-弹出法原理与实战

1. 项目概述:为什么我们需要O(1)的vector删除? 在C的日常开发里, std::vector 绝对是出场率最高的容器,没有之一。它简单、高效,提供了连续的存储空间,随机访问速度快如闪电。但凡是用过 vector 的开发…

2026/10/12 19:35:42 阅读更多 →
Zookeeper - 事务 ID 的生成规则与集群一致性关联

Zookeeper - 事务 ID 的生成规则与集群一致性关联

👋 大家好,欢迎来到我的技术博客! 📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。 🎯 本文将围绕Zookeeper这个话题展开,希望能为你带来一些启…

2026/10/15 14:18:40 阅读更多 →
Tomcat安全加固与运维管理实战指南

Tomcat安全加固与运维管理实战指南

1. Tomcat安全加固与运维管理概述作为Java生态中最广泛使用的Web容器之一,Tomcat在各类企业应用中承担着关键角色。我在金融行业的生产环境运维中,曾处理过因配置不当导致的安全事件,深刻体会到"安全不是功能,而是底线"…

2026/10/10 20:50:44 阅读更多 →

最新新闻

PS5远程串流优化实操:第三方客户端与参数调校完全指南

PS5远程串流优化实操:第三方客户端与参数调校完全指南

说到PS5远程串流,我估计大多数人的第一反应都是官方那个Remote Play App。能用,但也仅仅是“能用”。画面偶尔糊成一团、延迟飘忽不定、支持设备被卡得死死的,明明手里一台旗舰手机、一台轻薄本,结果玩起来跟十年前云游戏似的。我…

2026/10/15 23:23:42 阅读更多 →
AnyPS5串流方案从零搭建:让任意屏幕变成PS5显示器的完整指南

AnyPS5串流方案从零搭建:让任意屏幕变成PS5显示器的完整指南

AnyPS5这个项目,第一次看到标题时我以为是哪个硬件大神的魔改作品,把PS5塞进某个便携盒子之类的。研究了一圈才发现,它真正想表达的是“Any Device, PS5”——让你手头任何一块屏幕,都能变成PS5的显示器和控制器。说白了&#xff…

2026/10/15 23:23:42 阅读更多 →
本地AI绘图环境搭建全攻略:从硬件选型到性能优化

本地AI绘图环境搭建全攻略:从硬件选型到性能优化

1. 为什么要在本地搭一套AI绘图环境很多人第一次接触AI绘图,都是从网页版或者在线服务开始的。输入一段提示词,点一下生成,几秒钟就能拿到图。方便是真方便,但用久了问题就来了:免费额度用完了要充值,生成队…

2026/10/15 23:23:42 阅读更多 →
吃透Java面向对象四大基石:类、封装、继承、多态实战指南

吃透Java面向对象四大基石:类、封装、继承、多态实战指南

写 Java 的人应该都有过这么一段:键盘敲得飞快,类一个接一个往外蹦,可回过头看自己的代码,总觉得哪里不对劲。说不上是坏,但就是“味道”不对。后来能带新人了,我才慢慢想明白,问题不是语法不熟…

2026/10/15 23:23:42 阅读更多 →
前端多文件上传删除失效?FileList只读机制与解决方案

前端多文件上传删除失效?FileList只读机制与解决方案

1. 表单里那个“删不掉”的文件:一个前端老手也翻过车的经典场景如果你写过带文件上传的表单,大概率遇到过这种让人抓狂的情况:用户选了三个文件,点掉其中一个的删除按钮,界面上那个文件确实消失了,可一点提…

2026/10/15 23:23:42 阅读更多 →
2025前端十大语言与技术栈盘点:从JavaScript到全栈选型指南

2025前端十大语言与技术栈盘点:从JavaScript到全栈选型指南

聊前端语言的排行榜,在圈子里一向容易变成辩论赛。JavaScript、TypeScript、React、Vue、Svelte……每个人心里都有一杆秤,真排起名次来谁也说服不了谁。但对刚入行的人来说,这种争论反而很折磨——他们没有判断基准,只知道到处问…

2026/10/15 23:22:41 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →