Curator框架提供了一套高级的API, 简化了ZooKeeper的操作。 它增加了很多使用ZooKeeper开发的特性,可以处理ZooKeeper集群复杂的连接管理和重试机制。 这些特性包括:
1. 自动化的连接管理: 重新建立到ZooKeeper的连接和重试机制存在一些潜在的错误case。 Curator帮助你处理这些事情,对你来说是透明的。3. 提供了Recipes实现,基于这些Recipes可以创建很多复杂的分布式应用
Zookeeper在实际生产环境中应用比较广泛, 比如SOA的服务监控系统, hadoop, spark的分布式调度系统. Curator框架提供的优秀特性可以使得我们更加便捷的开发zookeeper应用.
org.apache.curator
curator-recipes
2.8.0
org.apache.curator
curator-client
2.8.0
org.apache.curator
curator-framework
2.8.0
//第一种方法: 工厂模式
//arg1: 重试时间间隔, arg2: 重试最大次数
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);
CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181",retryPolicy);
client.start();
//第二种方法: builder模式
CuratorFramework client = CuratorFrameworkFactory.builder().connectString(zkAddress)
.retryPolicy(new ExponentialBackoffRetry(1000, 3))
.connectionTimeoutMs(1000)
.sessionTimeoutMs(1000)
// etc. etc.
.build();
client.start();
package com.nxcjh.hadoop.examples.zookeeper.curator;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.utils.CloseableUtils;
public class CreateClientExample {
private static final String PATH = "/example/basic";
private static final String ZKADDRESS = "10.17.110.25:2181,10.17.110.32:2181,10.17.110.36:2181";
public static void main(String[] args) throws Exception {
CuratorFramework client = null;
try {
//1. 工厂模式
client = createSimple(ZKADDRESS);
client.start();
client.create().creatingParentsIfNeeded().forPath(PATH, "test".getBytes());
CloseableUtils.closeQuietly(client);
//2. builer模式
client = createWithOptions(ZKADDRESS, new ExponentialBackoffRetry(1000, 3), 1000, 1000);
client.start();
System.out.println(new String(client.getData().forPath(PATH)));
} catch (Exception ex) {
ex.printStackTrace();
} finally {
CloseableUtils.closeQuietly(client);
CloseableUtils.closeQuietly(client);
}
}
/**
* 工厂方法
* @param connectionString
* @return
*/
public static CuratorFramework createSimple(String connectionString) {
ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3);
return CuratorFrameworkFactory.newClient(connectionString, retryPolicy);
}
/**
* builder 模式
* @param connectionString
* @param retryPolicy
* @param connectionTimeoutMs
* @param sessionTimeoutMs
* @return
*/
public static CuratorFramework createWithOptions(String connectionString, RetryPolicy retryPolicy, int connectionTimeoutMs, int sessionTimeoutMs) {
return CuratorFrameworkFactory.builder().connectString(connectionString)
.retryPolicy(retryPolicy)
.connectionTimeoutMs(connectionTimeoutMs)
.sessionTimeoutMs(sessionTimeoutMs)
// etc. etc.
.build();
}
}
client.create().forPath("/head", new byte[0]);
client.delete().inBackground().forPath("/head");
client.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/head/child", new byte[0]);
client.getData().watched().inBackground().forPath("/test");
CuratorFramework提供的方法
方法名 | 描述 |
---|---|
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()作为一个原子操作提交 |
package com.nxcjh.hadoop.examples.zookeeper.curator;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
/**
*
* zk 客户端框架测试
* @author
*
*/
public class CuratorTest {
private static final String zkAddress = "10.17.110.25:2181,10.17.110.32:2181,10.17.110.36:2181";
private static CuratorFramework client = null;
/**
* 初始化客户端连接
*/
public void setup(){
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
client = CuratorFrameworkFactory.newClient(zkAddress, retryPolicy);
client.start();
System.out.println("客户端连接成功...");
}
public void init(){
client = CuratorFrameworkFactory.builder().connectString(zkAddress)
.retryPolicy(new ExponentialBackoffRetry(1000, 3))
.connectionTimeoutMs(1000)
.sessionTimeoutMs(1000)
// etc. etc.
.build();
client.start();
}
/**
* 创建节点
* @param client
* @param path
* @param createMode
* @param data
*/
public void createNode(String path,CreateMode createMode,String data){
try {
String res = client.create().withMode(createMode).forPath(path,data.getBytes());
System.out.println("创建'"+res+"'节点成功!");
} catch (Exception e) {
System.out.println("创建节点失败,elog="+e.getMessage());
}
}
/**
* 获取节点数据
* @param client
* @param path
* @return
*/
public String getNodeData(String path){
String res = null;
try {
res = new String(client.getData().forPath(path));
System.out.println("获取节点数据成功:"+res);
} catch (Exception e) {
System.out.println("获取数据失败,elog="+e.getMessage());
}
return res;
}
/**
* 更新节点数据
* @param path
* @param data
*/
public void updateNodeDate(String path,String data){
try {
client.setData().forPath(path,data.getBytes());
System.out.println("更新节点数据成功!");
} catch (Exception e) {
System.out.println("更新数据失败,elog="+e.getMessage());
}
}
/**
* 删除节点
* @param client
* @param path
*/
public void delNode(String path){
try {
client.delete().forPath(path);
System.out.println("删除节点成功!");
} catch (Exception e) {
System.out.println("删除节点失败,elog="+e.getMessage());
}
}
/**
* 关闭客户端
*/
public void close(){
client.close();
System.out.println("客户端关闭....");
}
public static void main(String[] args) throws Exception {
CuratorTest curator = new CuratorTest();
//工厂模式创建
curator.setup();
//builder模式创建
// curator.init();
// //创建节点
// curator.createNode("/my/zktest", CreateMode.PERSISTENT, "hello curator");
// //获取节点
// System.out.println(curator.getNodeData("/my/zktest"));
// //更新节点
// curator.updateNodeDate("/my/zktest", "hello tx");
// System.out.println(curator.getNodeData("/my/zktest"));
// //删除节点
curator.delNode("/my/zktest");
curator.close();
}
}
Event Type | Event Methods |
---|---|
CREATE | getResultCode() and getPath() |
DELETE | getResultCode() and getPath() |
EXISTS | getResultCode(), getPath() and getStat() |
GETDATA | getResultCode(), getPath(), getStat() and getData() |
SETDATA | getResultCode(), getPath() and getStat() |
CHILDREN | getResultCode(), getPath(), getStat(), getChildren() |
WATCHED | getWatchedEvent() |
CuratorFramework client = CuratorFrameworkFactory.builder().namespace("MyApp") ... build();
...
client.create().forPath("/test", data);
// node was actually written to: "/MyApp/test"
public void close();
public CuratorTransaction inTransaction() throws Exception;
public TempGetDataBuilder getData() throws Exception;
package com.nxcjh.hadoop.examples.zookeeper.curator;
import java.util.Collection;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.api.transaction.CuratorTransaction;
import org.apache.curator.framework.api.transaction.CuratorTransactionFinal;
import org.apache.curator.framework.api.transaction.CuratorTransactionResult;
public class TransactionExample {
public static void main(String[] args) {
}
public static Collection transaction(CuratorFramework client) throws Exception {
Collection results = client.inTransaction().create().forPath("/a/path", "some data".getBytes())
.and().setData().forPath("/another/path", "other data".getBytes())
.and().delete().forPath("/yet/another/path")
.and().commit(); // IMPORTANT!
for (CuratorTransactionResult result : results) {
System.out.println(result.getForPath() + " - " + result.getType());
}
return results;
}
public static CuratorTransaction startTransaction(CuratorFramework client) {
// start the transaction builder
return client.inTransaction();
}
public static CuratorTransactionFinal addCreateToTransaction(CuratorTransaction transaction) throws Exception {
// add a create operation
return transaction.create().forPath("/a/path", "some data".getBytes()).and();
}
public static CuratorTransactionFinal addDeleteToTransaction(CuratorTransaction transaction) throws Exception {
// add a delete operation
return transaction.delete().forPath("/another/path").and();
}
public static void commitTransaction(CuratorTransactionFinal transaction) throws Exception {
// commit the transaction
transaction.commit();
}
}