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
随机推荐
- atitit.GUI图片非规则按钮跟动态图片切换的实现模式总结java .net c# c++ web html js
atitit.GUI图片非规则按钮跟动态图片切换的实现模式总结java .net c# c++ web html js 1. 图片按钮的效果总结 1 1.1. 按钮图片自动缩放的. 1 1.2. 不要 ...
- 【Android】13.3 使用SQLite.NET-PCL访问SQLite数据库
分类:C#.Android.VS2015: 创建日期:2016-02-26 一.简介 本章开头已经说过了,SQLite.NET-PCL用起来很爽,这一节咱们看看怎样使用吧. 二.示例3运行截图 下面左 ...
- DB2中如何取得随机数
转自:http://blog.csdn.net/jionghan3855/article/details/2246738 在DB2数据库自定义产生指定位数的随机数函数. DB2产生随机数的函数:RAN ...
- WannaCry病毒应急处置
WannaCry病毒应急处置 病毒介绍 近期勒索病毒WannaCry大面积爆发,并迅速蔓延.被感染的机器,病毒会自动加密系统中的图片.文档.音频.视频等几乎所有类型的文件,必须缴纳高额勒索金(人民 ...
- android 批量上传图片
额外还需要NetUtil和服务器端UpLoadPicture package com.example.girdviewtest; import java.util.ArrayList;import j ...
- java服务端json结果集传值给前端的数据输出格式
在服务端输出json数据时按照一定的格式输出时间字段,fastjson支持两种方式:1.使用JSON.toJSONStringWithDateFormat方法2.JSON.toJSONString方法 ...
- 除去Scala的糖衣(13) -- Default Parameter Value
欢迎关注我的新博客地址:http://cuipengfei.me/ 好久没有写博客了,上一次更新竟然是一月份. 说工作忙都是借口,咋有空看美剧呢. 这半年荒废掉博客说到底就是懒,惯性的懒惰.写博客这事 ...
- php -- 可变变量
有时候使用可变变量名是很方便的.就是说,一个变量的变量名可以动态的设置和使用.一个普通的变量通过声明来设置,例如: <?php $a = 'hello'; ?> 一个可变变量获取了一个普通 ...
- FormData异步上传
1.代码片段一: ajaxUpload: function () { var url = this.$avatarForm.attr('action'), data = new FormData(th ...
- 事务基础知识-->Spring事务管理
Spring虽然提供了灵活方便的事务管理功能,但这些功能都是基于底层数据库本身的事务处理机制工作的.要深入了解Spring的事务管理和配置,有必要先对数据库事务的基础知识进行学习. 何为数据库事务 “ ...