02.ZooKeeper的Java客户端使用
1.ZooKeeper常用客户端比较
- zookeeper自带的客户端是官方提供的,比较底层、使用起来写代码麻烦、不够直接。
- Apache Curator是Apache的开源项目,封装了zookeeper自带的客户端,使用相对简便,易于使用。
- zkclient是另一个开源的ZooKeeper客户端,其地址:https://github.com/adyliu/zkclient生产环境不推荐使用。
<dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.6</version></dependency>
<dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>2.9.0</version></dependency>
<dependency><groupId>com.github.adyliu</groupId><artifactId>zkclient</artifactId><version>2.1.1</version></dependency>
- 初始化连接的问题: 在client与server之间握手建立连接的过程中,如果握手失败,执行所有的同步方法(比如create,getData等)将抛出异常
- 自动恢复(failover)的问题: 当client与一台server的连接丢失,并试图去连接另外一台server时, client将回到初始连接模式
- session过期的问题: 在极端情况下,出现ZooKeeper session过期,客户端需要自己去监听该状态并重新创建ZooKeeper实例
- 对可恢复异常的处理:当在server端创建一个有序ZNode,而在将节点名返回给客户端时崩溃,此时client端抛出可恢复的异常,用户需要自己捕获这些异常并进行重试
- 使用场景的问题:Zookeeper提供了一些标准的使用场景支持,但是ZooKeeper对这些功能的使用说明文档很少,而且很容易用错.在一些极端场景下如何处理,zk并没有给出详细的文档说明.比如共享锁服务,当服务器端创建临时顺序节点成功,但是在客户端接收到节点名之前挂掉了,如果不能很好的处理这种情况,将导致死锁
- 内部采用SLF4J 来输出日志
- 采用驱动器(driver)机制, 允许扩展和定制日志和跟踪处理
- 提供了一个TracerDriver接口, 通过实现addTrace()和addCount()接口来集成用户自己的跟踪框架
- 文档几乎没有
- 异常处理弱爆了(简单的抛出RuntimeException)
- 重试处理太难用了
- 没有提供各种使用场景的实现
- 只是一个底层实现
- 要用需要自己写大量的代码
- 很容易误用
- 需要自己处理连接丢失, 重试等
2.ZooKeeper原生客户端基本使用


public static void main(String[] args) throws IOException, KeeperException, InterruptedException{// 创建一个与服务器的连接 需要(服务端的 ip+端口号)(session过期时间)(Watcher监听注册)ZooKeeper zk = new ZooKeeper("192.168.110.100:2181", 3000, new Watcher(){// 监控所有被触发的事件public void process(WatchedEvent event){System.out.println(event.toString());}});System.out.println("OK!");// 创建一个目录节点/*** CreateMode:* PERSISTENT (持续的,相对于EPHEMERAL,不会随着client的断开而消失)* PERSISTENT_SEQUENTIAL(持久的且带顺序的)* EPHEMERAL (短暂的,生命周期依赖于client session)* EPHEMERAL_SEQUENTIAL (短暂的,带顺序的)*/zk.create("/path01", "data01".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);// 创建一个子目录节点zk.create("/path01/path01", "data01/data01".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);System.out.println(new String(zk.getData("/path01", false, null)));// 取出子目录节点列表System.out.println(zk.getChildren("/path01", true));// 创建另外一个子目录节点zk.create("/path01/path02", "data01/data02".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);System.out.println(zk.getChildren("/path01", true));// 修改子目录节点数据zk.setData("/path01/path01", "data01/data01-01".getBytes(), -1);byte[] datas = zk.getData("/path01/path01", true, null);String str = new String(datas, "utf-8");System.out.println(str);// 删除整个子目录 -1代表version版本号,-1是删除所有版本zk.delete("/path01/path01", -1);zk.delete("/path01/path02", -1);zk.delete("/path01", -1);System.out.println(str);Thread.sleep(15000);zk.close();System.out.println("OK");}
3.Apache Curator基本使用
public static void main(String[] args) throws Exception{CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", new RetryNTimes(10, 5000));client.start();// 连接// 获取子节点,顺便监控子节点List<String> children = client.getChildren().usingWatcher(new CuratorWatcher(){@Overridepublic void process(WatchedEvent event) throws Exception{System.out.println("监控: " + event);}}).forPath("/");System.out.println(children);// 创建节点String result = client.create().withMode(CreateMode.PERSISTENT).withACL(Ids.OPEN_ACL_UNSAFE).forPath("/test", "Data".getBytes());System.out.println(result);// 设置节点数据client.setData().forPath("/test", "111".getBytes());client.setData().forPath("/test", "222".getBytes());// 删除节点System.out.println(client.checkExists().forPath("/test"));client.delete().withVersion(-1).forPath("/test");System.out.println(client.checkExists().forPath("/test"));client.close();System.out.println("OK!");}
- create() 开始创建操作, 可以调用额外的方法(比如方式mode 或者后台执行background) 并在最后调用forPath()指定要操作的ZNode
- delete() 开始删除操作. 可以调用额外的方法(版本或者后台处理version or background)并在最后调用forPath()指定要操作的ZNode
- checkExists() 开始检查ZNode是否存在的操作. 可以调用额外的方法(监控或者后台处理)并在最后调用forPath()指定要操作的ZNode
- getData() 开始获得ZNode节点数据的操作. 可以调用额外的方法(监控、后台处理或者获取状态watch, background or get stat) 并在最后调用forPath()指定要操作的ZNode
- setData() 开始设置ZNode节点数据的操作. 可以调用额外的方法(版本或者后台处理) 并在最后调用forPath()指定要操作的ZNode
- getChildren() 开始获得ZNode的子节点列表。 以调用额外的方法(监控、后台处理或者获取状态watch, background or get stat) 并在最后调用forPath()指定要操作的ZNode
- inTransaction() 开始是原子ZooKeeper事务. 可以复合create, setData, check, and/or delete 等操作然后调用commit()作为一个原子操作提交
client.getCuratorListenable().addListener(new CuratorListener(){@Overridepublic void eventReceived(CuratorFramework client, CuratorEvent event) throws Exception{System.out.println("事件: " + event);}});client.getConnectionStateListenable().addListener(new ConnectionStateListener(){@Overridepublic void stateChanged(CuratorFramework client, ConnectionState newState){System.out.println("连接状态事件: " + newState);}});client.getUnhandledErrorListenable().addListener(new UnhandledErrorListener(){@Overridepublic void unhandledError(String message, Throwable e){System.out.println("错误事件:" + message);}});
- CuratorListenable:当使用后台线程操作时,后台线程执行完成就会触发,例如:client.getData().inBackground().forPath("/test");后台获取节点数据,获取完成之后触发。
- ConnectionStateListenable:当连接状态变化时触发。
- UnhandledErrorListenable:当后台操作发生异常时触发。
事件类型 事件返回数据CREATE getResultCode() and getPath()DELETE getResultCode() and getPath()EXISTS getResultCode(), getPath() and getStat()GET_DATA getResultCode(), getPath(), getStat() and getData()SET_DATA getResultCode(), getPath() and getStat()CHILDREN getResultCode(), getPath(), getStat(), getChildren()SYNC getResultCode(), getStat()GET_ACL getResultCode(), getACLList()SET_ACL getResultCode()TRANSACTION getResultCode(), getOpResults()WATCHED getWatchedEvent()GET_CONFIG getResultCode(), getData()RECONFIG getResultCode(), getData()
CuratorFramework client = CuratorFrameworkFactory.builder().namespace("MyApp") ... build();
CuratorTempFramework client = CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181")// 连接串.retryPolicy(new RetryNTimes(10, 5000))// 重试策略.connectionTimeoutMs(100) // 连接超时.sessionTimeoutMs(100) // 会话超时.buildTemp(100, TimeUnit.MINUTES); // 临时客户端并设置连接时间
public void close();public CuratorTransaction inTransaction() throws Exception;public TempGetDataBuilder getData() throws Exception;
- ExponentialBackoffRetry:重试一定次数,每次重试sleep更多的时间
- RetryNTimes:重试N次
- RetryOneTime:重试一次
- RetryUntilElapsed:重试一定的时间
-------------------------------------------------------------------------------------------------------------------------------
02.ZooKeeper的Java客户端使用的更多相关文章
- Zookeeper的java客户端API使用方法(五)
前面几篇博文,我们简单的介绍了一下zookeeper,如何安装zookeeper集群,以及如何使用命令行等.这篇博文我们重点来看下Zookeeper的java客户端API使用方式. 创建会话 客户端可 ...
- ZooKeeper学习总结(2)——ZooKeeper开源Java客户端ZkClient使用
zkclient是zookeeper的Java客户端.它让Zookeeper API 使用起来更简单:它非常方便订阅各种事件并自动重新绑定事件(会话建立.节点修改.节点删除.子节点变更等):它提供了s ...
- zookeeper的Java客户端API
zookeeper作为一个分布式服务框架,主要用来解决分布式数据一致性问题,对多种语言提供了API.这里主要记录下JAVA客户端API的使用. 1.创建会话 客户端可以通过创建一个ZooKeeper实 ...
- Zookeeper 的 java 客户端都有哪些?
java 客户端:zk 自带的 zkclient 及 Apache 开源的 Curator.
- [转载] ZooKeeper的Java客户端API
转载自 http://www.cnblogs.com/ggjucheng/p/3370359.html http://zookeeper.apache.org/doc/trunk/javaExampl ...
- 六:ZooKeeper的java客户端api的使用
一:客户端链接测试 package com.yeepay.sxf.createConnection; import java.io.IOException; import org.apache.zoo ...
- ZooKeeper:Java客户端网络处理
了解ZooKeeper客户端的实现,对于使用ZooKeeper的客户端非常重要. 通过对客户端源码的阅读,了解了如下信息: 创建ZooKeeper对象时,应会创建一个ClientCnxn(代表了客户端 ...
- 12. ZooKeeper之Java客户端API使用—创建会话。
转自:https://blog.csdn.net/en_joker/article/details/78686649 客户端可以通过创建一个ZooKeeper(org.apache.zookeeper ...
- 13.Zookeeper的java客户端API使用方法
转自:https://blog.csdn.net/jiuqiyuliang/article/details/56012027
随机推荐
- php保存快捷方式到桌面
/** * 保存首页到桌面 */ public function save_shortcut() { $shortcut = "[DEFAULT] BASEURL=http://www.19 ...
- atitit,it人怎么样才容易事业成功?? 有以下五种性格的人容易成功
atitit,it人怎么样才容易事业成功?? 有以下五种性格的人容易成功 有以下五种性格的人容易成功 一.不撞南墙不回头的人:由于这种人有脚踏实地,做事拼命.不撞南墙不回头的性格特点, 势有不到黄河心 ...
- Atitit.编程语言的主要的种类and趋势 逻辑式语言..函数式语言...命令式语言
Atitit.编程语言的主要的种类and趋势 逻辑式语言..函数式语言...命令式语言 1. 编程语言的主要的种类 逻辑式语言..函数式语言...命令式语言 1 2. 逻辑式语言,,不必考虑实现过程而 ...
- 应用SVN比较文件定位修改
用SVN checkout一个版A本到一个目录中,再从别的地方找到版本B复制到版本A所在的目录中,选择复制和替换,再要比较的文件上右键-->SVN-->diff
- jMiniLang设计思路
前言 项目地址:https://github.com/bajdcc/jMiniLang 演示视频:https://www.bilibili.com/video/av13294962 jMiniLang ...
- dp之多重背包poj2392
题意:有k种石头,高为hi,在不超过ai的高度下,这种石头可以放置,有ci种这个石头,求这些石头所能放置的最高高度......... 思路:以往的什么硬币种数,最大硬币数之类的,他们的硬币都已经是排好 ...
- vuex 开始
每一个vuex的应用的核心都是store(仓库),store基本上就是一个容器,它包含着你的应用中大部分的状态(state),vuex和单纯的全局对象有以下两点不同: 1,vuex的状态存储是响应式的 ...
- jquery文件导入问题
开发前台web,导入jquery文件的时候最好用 <script type="text/javascript" src="path"></sc ...
- PDF文件的加载及展示
项目需要显示PDF文件,于是遍寻了网络,发现的方法以下几种: 1.使用UIWebView加载,没啥说的,根据文件路径,网络或者本地皆可,创建一个NSURLRequest,然后用webView加载就可以 ...
- 一款基于jquery的喜欢动画按钮
今天给大家带来一款基于jquery的喜欢动画按钮.这个实例中给了三种动画特效.效果图如下: 在线预览 源码下载 实现的代码. html代码: <p class='heading'> C ...