最近很多小伙伴都在问Zookeeper客户端Curator基本API和zookeeper客户端工具这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展07_zookeeper的客户端工
最近很多小伙伴都在问Zookeeper客户端Curator基本API和zookeeper客户端工具这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展07_zookeeper的客户端工具curator_基本api、5.zookeeper集成Java项目curator客户端、Apache Curator 2.7.1 发布,zookeeper 客户端简化、Apache Curator 2.8.0 发布,简化 zookeeper 客户端等相关知识,下面开始了哦!
本文目录一览:- Zookeeper客户端Curator基本API(zookeeper客户端工具)
- 07_zookeeper的客户端工具curator_基本api
- 5.zookeeper集成Java项目curator客户端
- Apache Curator 2.7.1 发布,zookeeper 客户端简化
- Apache Curator 2.8.0 发布,简化 zookeeper 客户端
Zookeeper客户端Curator基本API(zookeeper客户端工具)
在使用zookeper的时候一般不使用原生的API,Curator,解决了很多Zookeeper客户端非常底层的细节开发工作,包括连接重连、反复注册Watcher和NodeExistsException异常等等。
Curator包含了几个包:
- curator-framework:对zookeeper的底层api的一些封装
- curator-client:提供一些客户端的操作,例如重试策略等
- curator-recipes:封装了一些高级特性,如:Cache事件监听、选举、分布式锁、分布式计数器、分布式Barrier等
Maven依赖:
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.12.0</version>
</dependency>
====================基本的API==============
1.创建会话
(1)静态工厂创建会话
源码如下:
public static CuratorFramework newClient(String connectString, RetryPolicy retryPolicy)
{
return newClient(connectString, DEFAULT_SESSION_TIMEOUT_MS, DEFAULT_CONNECTION_TIMEOUT_MS, retryPolicy);
}
/**
* Create a new client
*
* @param connectString list of servers to connect to
* @param sessionTimeoutMs session timeout
* @param connectionTimeoutMs connection timeout
* @param retryPolicy retry policy to use
* @return client
*/
public static CuratorFramework newClient(String connectString, int sessionTimeoutMs, int connectionTimeoutMs, RetryPolicy retryPolicy)
{
return builder().
connectString(connectString).
sessionTimeoutMs(sessionTimeoutMs).
connectionTimeoutMs(connectionTimeoutMs).
retryPolicy(retryPolicy).
build();
}
测试代码:采用4个参数的方法
private static CuratorFramework getClient() {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
return CuratorFrameworkFactory.newClient("localhost:2181", 5000, 3000, retryPolicy);
}
参数解释:
connectString: 链接 URL
sessionTimeoutMs: 会话超时时间,单位毫秒,默认60000ms
connectionTimeoutMs: 连接创建超时时间,单位毫秒,默认60000ms
retryPolicy: 重试策略,内建有四种重试策略,也可以自行实现RetryPolicy接口
1.RetryUntilElapsed(int maxElapsedTimeMs, int sleepMsBetweenRetries)
以sleepMsBetweenRetries的间隔重连,直到超过maxElapsedTimeMs的时间设置
2.RetryNTimes(int n, int sleepMsBetweenRetries)
指定重连次数
3.RetryOneTime(int sleepMsBetweenRetry)
重连一次,简单粗暴
4.ExponentialBackoffRetry
ExponentialBackoffRetry(int baseSleepTimeMs, int maxRetries)
ExponentialBackoffRetry(int baseSleepTimeMs, int maxRetries, int maxSleepMs)
时间间隔 = baseSleepTimeMs * Math.max(1, random.nextInt(1 << (retryCount + 1)))
(2)第二种方法:
private static CuratorFramework getClient() {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.builder().connectString(URL)
.sessionTimeoutMs(5000).connectionTimeoutMs(5000).retryPolicy(retryPolicy).build();
return client;
}
(3)创建包含隔离命名空间的会话(下面也基于这种方式)
private static CuratorFramework getClient() {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.builder().connectString(URL).sessionTimeoutMs(5000)
.connectionTimeoutMs(5000).retryPolicy(retryPolicy).namespace("curator").build();
return client;
}
得到会话之后,调用 client.start(); 即可启动客户端。
原来zookeper数据结构如下:
关闭会话的方法如下:(必须在开启之后在关闭,否则会报非法状态异常)
client.close();
或者:
CloseableUtils.closeQuietly(client);
2.创建节点
这个可以递归创建父节点并不抛出异常;指定节点类型(临时、顺序、临时永久),默认是永久
CuratorFramework client = getClient();
client.start();
// 创建普通节点(默认是持久节点),内容为空
client.create().forPath("/t1");
// 创建普通节点(默认是持久节点)
client.create().forPath("/t2", "123456".getBytes());
// 创建永久顺序节点
client.create().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath("/t3", "123456".getBytes());
// 地柜创建,如果父节点不存在也会创建
client.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT_SEQUENTIAL)
.forPath("/t4/t41/t411", "123456".getBytes());
结果:
3.删除节点
也可以递归删除。当然下面的多个流式接口可以随意组合。
CuratorFramework client = getClient();
client.start();
// 删除子节点,只能删除叶子节点
client.delete().forPath("/t2");
// 递归删除
client.delete().deletingChildrenIfNeeded().forPath("/t4/t41");
// 指定版本进行删除
client.delete().withVersion(0).forPath("/t1");
// 强制删除。guaranteed()接口是一个保障措施,只要客户端会话有效,那么Curator会在后台持续进行删除操作,直到删除节点成功。
client.delete().guaranteed().forPath("/t30000000002");
结果:
4.读取节点数据---可以注册监听
// 读取数据不获取stat
byte[] forPath = client.getData().forPath("/t4");
System.out.println(new String(forPath, "UTF-8"));
// 读取数据且获取stat
Stat stat = new Stat();
byte[] forPath2 = client.getData().storingStatIn(stat).forPath("/t4");
System.out.println(new String(forPath2, "UTF-8"));
System.out.println(stat);
// 注册观察者,当节点变动时触发
byte[] data = client.getData().usingWatcher(new Watcher() {
@Override
public void process(WatchedEvent event) {
System.out.println(event.getType());
}
}).forPath("/t4");
System.out.println("/t4: " + new String(data));
5.更新数据节点数据
// 更新数据,返回的是stat
Stat forPath = client.setData().forPath("/t4", "data".getBytes());
// 更新一个节点的数据内容,强制指定版本进行更新
Stat stat = new Stat();
client.getData().storingStatIn(stat).forPath("/t4");
Stat forPath2 = client.setData().withVersion(stat.getVersion()).forPath("/t4", "data222".getBytes());
6. 检查节点是否存在
Stat forPath = client.checkExists().forPath("/t4");
if (forPath != null) {
System.out.println("exists");
} else {
System.out.println("not exists");
}
7. 获取某个节点的所有子节点路径--这个获取的是子节点的名称且不带/
List<String> forPath = client.getChildren().forPath("/");
System.out.println(forPath);
结果:
[t4]
8.事务
允许作为一个原子操作进行提交。
// inTransaction( )方法开启一个ZooKeeper事务.可以复合create, setData, check, and/or delete 等操作然后调用commit()作为一个原子操作提交
client.inTransaction().
check().forPath("/t4").
and().
create().withMode(CreateMode.EPHEMERAL).forPath("/t3", "data".getBytes()).
and().
setData().forPath("/t3", "data2".getBytes()).
and().
commit();
9. 异步接口

响应码(#getResultCode())
如下:
client.create().inBackground(new BackgroundCallback() {
@Override
public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception {
System.out.println(curatorEvent.getType() + " " + curatorEvent.getResultCode());
}
}, Executors.newFixedThreadPool(2)).forPath("/t2", "测试值".getBytes());
注意: 如果#inBackground()方法不指定executor,那么会默认使用Curator的EventThread去进行异步处理。
====================监听机制==============
Curator的监听实现是对zookeeper原生监听方法的高级封装,主要体现在两点:监听重复注册,事件发生信息。而且监听事件返回详细的信息,如变动的节点信息,节点的value等。
Curator 提供了3个接口:PathChildrenCacheListener、 NodeCache、TreeCache。三个接口都可以对一个不存在的节点进行监听。
1. PathChildrenCache
对指定的路径节点的一级子目录进行监听,不对该节点的操作进行监听,对其子目录的节点进行增、删、改的操作监听。
如果监听的节点不存在会创建节点,如果节点是多级目录会递归创建,节点删除之后监听事件会失效。
如下:
/**
*
* @param client
* @throws Exception
*/
private static void setListenterThreeOne(CuratorFramework client) throws Exception {
PathChildrenCache childrenCache = new PathChildrenCache(client, "/t4", true);
PathChildrenCacheListener childrenCacheListener = new PathChildrenCacheListener() {
@Override
public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
ChildData data = event.getData();
switch (event.getType()) {
case CHILD_ADDED:
System.out.println("CHILD_ADDED : " + data.getPath() + " 数据:" + data.getData());
break;
case CHILD_REMOVED:
System.out.println("CHILD_REMOVED : " + data.getPath() + " 数据:" + data.getData());
break;
case CHILD_UPDATED:
System.out.println("CHILD_UPDATED : " + data.getPath() + " 数据:" + data.getData());
break;
default:
break;
}
}
};
// 在注册监听器的时候,如果传入此参数,当事件触发时,逻辑由线程池处理。如果不传会采用默认的线程池
ExecutorService pool = Executors.newFixedThreadPool(2);
// childrenCache.getListenable().addListener(childrenCacheListener);
childrenCache.getListenable().addListener(childrenCacheListener, pool);
// 设置监听模式
childrenCache.start(StartMode.BUILD_INITIAL_CACHE);
}
StartMode:初始化方式
POST_INITIALIZED_EVENT:异步初始化。初始化后会触发事件。如果节点不存在会创建节点。如果节点下面有子节点会触发CHILD_ADDED事件。
NORMAL:异步初始化。如果节点不存在会创建节点。如果节点下面有子节点会触发CHILD_ADDED事件。
BUILD_INITIAL_CACHE:同步初始化。如果节点不存在会创建节点。如果节点下面有子节点会触发CHILD_ADDED事件。
2.NodeCache
对一个节点进行监听,监听事件包括指定的路径节点的增、删、改的操作。
可以对一个不存在的节点进行监控,当节点创建之后会触发对应事件;节点被删除并且重建之后事件也仍然。
// Node Cache 监控本节点的变化情况 连接 目录 是否压缩
// 监听本节点的变化 节点可以进行修改操作 删除节点后会再次创建(空节点)
private static void setListenterThreeTwo(CuratorFramework client) throws Exception {
ExecutorService pool = Executors.newCachedThreadPool();
// 设置节点的cache
final NodeCache nodeCache = new NodeCache(client, "/t5", false);
nodeCache.getListenable().addListener(new NodeCacheListener() {
@Override
public void nodeChanged() throws Exception {
System.out.println("the test node is change and result is :");
System.out.println("path : " + nodeCache.getCurrentData().getPath());
System.out.println("data : " + new String(nodeCache.getCurrentData().getData()));
System.out.println("stat : " + nodeCache.getCurrentData().getStat());
}
});
nodeCache.start();
}
3.TreeCache
监控指定节点和节点下的所有的节点的变化--无限监听 ,也就是可以监听子孙目录。
可以对一个不存在的节点进行监控,当节点创建之后会触发对应事件;节点被删除并且重建之后事件也仍然。
// 监控 指定节点和节点下的所有的节点的变化--无限监听
private static void setListenterThreeThree(CuratorFramework client) throws Exception {
// 设置节点的cache
TreeCache treeCache = new TreeCache(client, "/t5");
// 设置监听器和处理过程
treeCache.getListenable().addListener(new TreeCacheListener() {
@Override
public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
ChildData data = event.getData();
if (data != null) {
switch (event.getType()) {
case NODE_ADDED:
System.out.println("NODE_ADDED : " + data.getPath() + " 数据:" + new String(data.getData()));
break;
case NODE_REMOVED:
System.out.println("NODE_REMOVED : " + data.getPath() + " 数据:" + new String(data.getData()));
break;
case NODE_UPDATED:
System.out.println("NODE_UPDATED : " + data.getPath() + " 数据:" + new String(data.getData()));
break;
default:
break;
}
} else {
System.out.println("data is null : " + event.getType());
}
}
});
// 开始监听
treeCache.start();
}
补充:上面的三个接口在设置监听器的时候都可以传入自定义的线程池,也可不传,如下:
// 在注册监听器的时候,如果传入此参数,当事件触发时,逻辑由线程池处理。如果不传会采用默认的线程池
ExecutorService pool = Executors.newFixedThreadPool(2);
// childrenCache.getListenable().addListener(childrenCacheListener);
childrenCache.getListenable().addListener(childrenCacheListener, pool);
07_zookeeper的客户端工具curator_基本api
【zk原生api的不足之处】
* 不能自动超时重连,需要手动操作
* watcher事件注册一次后就会失效
* 不支持递归创建节点
【 Apache curator 】
* 解决了watcher的注册一次就失效的问题
* api相对更加简单易用
* 提供更多的解决方案并且实现简单:如分布式锁
* 提供了常用的zk工具类
【实例化zk客户端的多种重试机制】
package com.zk.demo;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.*;
/**
* Created by HigginCui on 2018/9/23.
*/
public class CuratorClient {
public CuratorFramework client = null;
public static final String zkServerPath = "127.0.0.1";
/**
* 构造方法中实例化zk客户端
*/
public CuratorClient() {
/**
* 同步创建zk示例,原生api是异步的
* curator连接zk的策略:ExponentialBackoffRetry
*
* ExponentialBackoffRetry(int baseSleepTimeMs, int maxRetries)
* baseSleepTimeMs:初始sleep的时间
* maxRetries:最大重试次数
* maxSleepMs:最大充实实际那
*/
RetryPolicy retryPolicy1 = new ExponentialBackoffRetry(1000, 3);
/**
* curator连接zk的策略:RetryNTimes
*
* RetryNTimes(int n, int sleepMsBetweenRetries)
* n:重试的次数
* sleepMsBetweenRetries:每次重试的间隔的时间
*/
RetryPolicy retryPolicy2 = new RetryNTimes(3, 5000);
/**
* curator连接zk的策略:RetryOneTime
*
* RetryOneTime(int sleepMsBetweenRetry)
* sleepMsBetweenRetry:每次重试间隔的时间
*/
RetryPolicy retryPolicy3 = new RetryOneTime(3000);
/**
* curator连接zk的策略:RetryForever
*
* RetryForever(int retryIntervalMs)
* 永远重试,不推荐
*/
RetryPolicy retryPolicy4 = new RetryForever(5000);
/**
* curator连接zk的策略:RetryUntilElapsed
*
* RetryUntilElapsed(int maxElapsedTimeMs, int sleepMsBetweenRetries)
* maxElapsedTimeMs:最大重试时间
* sleepMsBetweenRetries:每次重试间隔
* 重试时间超过maxElapsedTimeMs后,就不在重试
*/
RetryPolicy retryPolicy5 = new RetryUntilElapsed(2000, 3000);
client = CuratorFrameworkFactory.builder()
.connectString(zkServerPath)
.sessionTimeoutMs(10000)
.retryPolicy(retryPolicy2)
.namespace("workspace")
.build();
client.start();
}
public void closeClient() {
if (null != client) {
this.client.close();
}
}
}
【创建节点】
package com.zk.demo;
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
/**
* Created by HigginCui on 2018/9/23.
*/
public class CuratorClientTest {
public static void main(String[] args) throws Exception{
CuratorFramework client = new CuratorClient().client;
boolean isCuratorStarted = client.isStarted();
System.out.println("当前客户端是否正常连接:"+isCuratorStarted);
//创建节点
String nodePath = "/curator/ccc1";
byte[] data = "hahaha".getBytes();
client.create()
.creatingParentsIfNeeded()
.withMode(CreateMode.PERSISTENT)
.withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
.forPath(nodePath,data);
}
}
【运行结果】
【更新节点数据】
//更新节点数据
byte[] newData = "xixixi".getBytes();
client.setData()
.withVersion(0)
.forPath(nodePath,newData);
【运行结果】
【删除节点】
//删除节点
client.delete()
.guaranteed() //如果删除失败,那么在后端还是会继续删除,直到成功
.deletingChildrenIfNeeded() //如果有子节点会一并删除
.withVersion(1)
.forPath(nodePath);
【运行结果】
【读取节点的数据】
//读取节点数据
Stat stat = new Stat();
byte[] data = client.getData()
.storingStatIn(stat)
.forPath(nodePath);
System.err.println("节点 "+nodePath+" 的数据为:"+new String(data)+",version为:"+stat.getVersion());
先在zk上设置好数据
【运行结果】
【查询子节点】
//查询子节点
List<String> childNodes = client.getChildren()
.forPath(nodePath);
for (String childNode : childNodes){
System.out.println("childNode = "+childNode);
}
提前创建好一批子节点
【运行结果】
【判断节点是否存在】
//判断节点是否存在,如果节点不存在则为空
Stat statExist = client.checkExists()
.forPath(nodePath);
System.err.println(statExist);
Stat statExist2 = client.checkExists()
.forPath(nodePath+"/lll"); //这里故意设置一个不存在的节点
System.err.println(statExist2);
【运行结果】
5.zookeeper集成Java项目curator客户端
创建了一个SpringBoot
项目,引入pom
依赖
<!--zookeeper-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
配置application.yml
属性
curator:
#重试次数
maxRetries: 3
#重试间隔时间
baseSleepTimeMs: 1000
# zookeeper 地址 多个可用逗号分隔127.0.0.1:2181,127.0.0.1:2182
connectString: 192.168.106.128:2181
# session超时时间
sessionTimeoutMs: 60000
# 连接超时时间
connectionTimeoutMs: 5000
path: /distributed-lock
配置注入Bean
package com.example.zkConfig;
import lombok.Data;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.RetryNTimes;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
public class ZookeeperConfig {
@Value("${curator.maxRetries}")
private int maxRetries;
@Value("${curator.baseSleepTimeMs}")
private int baseSleepTimeMs;
@Value("${curator.connectString}")
private String connectString;
@Value("${curator.sessionTimeoutMs}")
private int sessionTimeoutMs;
@Value("${curator.connectionTimeoutMs}")
private int connectionTimeoutMs;
@Value("${curator.path}")
private String path;
//调用start初始化方法
@Bean(initMethod = "start")
public CuratorFramework curatorFramework(){
return CuratorFrameworkFactory.newClient(
this.connectString,
this.sessionTimeoutMs,
this.connectionTimeoutMs,
new RetryNTimes(this.maxRetries,this.connectionTimeoutMs)
);
}
}
测试文件ZkTest
一些基本操作
package com.example;
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBoottest;
@SpringBoottest
public class ZkTest {
@Autowired
private CuratorFramework curatorFramework;
@Test
public void test1() throws Exception {
//创建持久节点
// String s = curatorFramework.create().forPath("/test-node1");
// 创建临时序号节点
String s = curatorFramework.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/test-node2", "abc".getBytes());
System.out.println(s);
}
@Test
public void test2() throws Exception {
//获取节点的数据
byte[] bytes = curatorFramework.getData().forPath("/test-node1");
System.out.println(new String(bytes));
}
@Test
public void test3() throws Exception {
//修改节点的数据
curatorFramework.setData().forPath("/test-node1","你好".getBytes());
//获取节点的数据
byte[] bytes = curatorFramework.getData().forPath("/test-node1");
System.out.println(new String(bytes));
}
@Test
public void test4() throws Exception {
//创建若父节点不存在则先创建父节点
String s = curatorFramework.create().creatingParentsIfNeeded().forPath("/node-parent/node-1");
System.out.println(s);
}
@Test
public void test5() throws Exception {
//删除父节点 子节点存在也一并删除
curatorFramework.delete().guaranteed().deletingChildrenIfNeeded().forPath("/node-parent");
}
}
总结
以上是小编为你收集整理的5.zookeeper集成Java项目curator客户端全部内容。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。
原文地址:https://blog.csdn.net/Smy_0114/article/details/122693744
Apache Curator 2.7.1 发布,zookeeper 客户端简化
Apache Curator 2.7.1 发布了,zookeeper 的客户端调用过于复杂,Apache Curator 就是为了简化zookeeper客户端调用而生,利用它,可以更好的使用zookeeper。
改进记录:
Bug
[CURATOR-175] - If zookeeper is down when discovery is started, it fails to register when the zookeeper comes up for the first time.
[CURATOR-179] - Sequential path creation of /somepath/N throws exception
[CURATOR-181] - discovery: registration of wrong/old service instance on RECONNECT
Improvement
[CURATOR-111] - CuratorFramework.Builder should allow adding multiple auths
[CURATOR-140] - Support the initial data for the node in InterProcessReadWriteLock
[CURATOR-166] - Make ZKPaths accept more than one child
[CURATOR-170] - ChildReaper would benefit by being able to manage multiple paths
[CURATOR-176] - Currently difficult to write ServiceDiscovery admin console
[CURATOR-177] - Pull request: Use Curator in thread names
Apache Curator 2.8.0 发布,简化 zookeeper 客户端
Apache Curator 2.8.0 发布,此版本的 Apache Curator Java 库让 Apache Zookeeper 使用起来更方便,详细更新信息如下:
Bug 修复:
[CURATOR-154] - PersistentEphemeralNode May Fail to Apply Updated Data
[CURATOR-164] - curator-x-discovery: unregisterService is not guaranteed to remove the service, due to reconnectListener concurrency issue
[CURATOR-168] - Background protected mode incorrectly sets Event name to just ZNode name. Should be full path.
[CURATOR-173] - InterProcessSemaphoreV2 nodes not reapable
[CURATOR-182] - TreeCache breaks when root node is removed
[CURATOR-183] - TreeCache not properly handling repeated add/removal of root node
[CURATOR-187] - ChildReaper does not respect built in leader election
[CURATOR-190] - PersistentEphemeralNode.Mode.PROTECTED_EPHEMERAL creates new node on recreate
[CURATOR-202] - LeaderSelector node is not removed on connection loss if reconnected to the same session
[CURATOR-210] - Unit tests using server.close() are fragile.
[CURATOR-211] - Fix InterProcessReadWriteLock#readLockPredicate() index validation issue
性能改进:
[CURATOR-203] - ChildReaper can be unstable when there are large ZNodes
[CURATOR-204] - Use the latest apache parent pom
详细信息请查看发行页面。
最新源代码可从 Apache 镜像获得:
http://www.apache.org/dyn/closer.cgi/curator/
zookeeper 的客户端调用过于复杂,Apache Curator 就是为了简化zookeeper客户端调用而生,利用它,可以更好的使用zookeeper。
关于Zookeeper客户端Curator基本API和zookeeper客户端工具的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于07_zookeeper的客户端工具curator_基本api、5.zookeeper集成Java项目curator客户端、Apache Curator 2.7.1 发布,zookeeper 客户端简化、Apache Curator 2.8.0 发布,简化 zookeeper 客户端等相关内容,可以在本站寻找。
本文标签: