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
随机推荐
- Python操作列表常用方法
Python操作列表的常用方法. 列表常用的方法操作列表以及小例子: 1. Append 在列表末尾添加元素,需在列表末尾添加元素,需要注意几个点: A. append中添加的参数是作为一个整体 &g ...
- Atitit. 悬浮窗口的实现 java swing c# .net c++ js html 的实现
Atitit. 悬浮窗口的实现 java swing c# .net c++ js html 的实现 1. 建立悬浮窗口引用代码 1 1.1. 定义悬浮窗口,设置this主窗口引用,是为了在悬浮窗口中 ...
- Python @ddt.file_data() 为.yml 文件实例
一,创建login.yml 文件(以登录接口为例) 1,创建 login.yml 文件,内容如下图: 打印login.yml 文件,代码及显示效果如下: 代码: import yaml,jsonf = ...
- maven中配置jdk版本
1 maven 中配置 <build> <plugins> <plugin> <groupId>org.apache.maven.plugins< ...
- 【转】在MAC下配置MySQL 5.7 数据库的编码问题
1.MySQL 5.7 for MAC 默认没有my.cnf文件 ,首先 新建my.cnf文件: 2.在my.cnf文件追加 1 2 3 4 5 6 7 8 [mysqld] character-se ...
- oracle 函数判断字符串是否包含图片格式
首先是写一个分割字符串的函数,返回table类型 CREATE OR REPLACE FUNCTION fn_split (p_str IN VARCHAR2, p_delimiter IN VARC ...
- FreeRTOS官方翻译文档——第二章 队列管理
2.1 概览基于 FreeRTOS 的应用程序由一组独立的任务构成——每个任务都是具有独立权限的小程序.这些独立的任务之间很可能会通过相互通信以提供有用的系统功能.FreeRTOS 中所有的通信与同步 ...
- malloc,我误解你了
malloc用于动态申请内存,这个学过C语言的都知道.忘记了在哪本书上看到,malloc申请的内存不一定是连续,于是一直记住了.这句话有错吗?没有!但是当时只是记住了这个知识点,而没有深入的思考.直到 ...
- 获取页面的checkbox,并给参数赋值
需求: 需要发送的请求:
- [转]hadoop,spark,storm,pig,hive,mahout等到底有什么区别和联系?
摘自知乎大神的论述 作者:Xiaoyu Ma链接:https://www.zhihu.com/question/27974418/answer/38965760来源:知乎著作权归作者所有,转载请联系作 ...