Curator是Netflix公司开源的一套zookeeper客户端框架,解决了很多Zookeeper客户端非常底层的细节开发工作,包括连接重连、反复注册Watcher和NodeExistsException异常等。
在编写代码之前,你的环境需要有安装并启动zookeeper服务, 接下来正式开始编程。
- 添加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>
- 编写zookeeper的客户端
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import java.util.ArrayList;
import java.util.List;
public class CuratorClient {
private CuratorFramework client;
public CuratorClient(String zkAddress, int sessionTimeoutMs, int connectionTimeoutMs) {
this.client = connectionZookeeper(zkAddress, sessionTimeoutMs, connectionTimeoutMs);
}
public CuratorClient(String zkAddress) {
this.client = connectionZookeeper(zkAddress, 12000, 12000);
}
private CuratorFramework connectionZookeeper(String zkAddress, int sessionTimeMs, int connectionTimeoutMs) {
ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 5);
CuratorFramework client = CuratorFrameworkFactory.builder()
.connectString(zkAddress)
.sessionTimeoutMs(sessionTimeMs)
.connectionTimeoutMs(connectionTimeoutMs)
.retryPolicy(retryPolicy)
.build();
client.start();
return client;
}
public CuratorFramework getClient() {
return this.client;
}
/**
* 创建一个节点
*/
public void createNode(String nodePath, byte[] nodeData, CreateMode createMode) {
try {
client.create()
.creatingParentContainersIfNeeded()
.withMode(createMode)
.forPath(nodePath, nodeData);
} catch (Exception e) {
System.out.println("Create znode failed, znode : " + nodePath);
e.printStackTrace();
}
}
/**
* 删除一个子节点
*/
public void deleteChildNode(String childNodePath) {
try {
client.delete().forPath(childNodePath);
} catch (Exception e) {
System.out.println("Delete childNode failed, znode : " + childNodePath);
e.printStackTrace();
}
}
/**
* 删除一个父节点
*/
public void deleteParentNode(String parentNodePath) {
try {
client.delete()
.deletingChildrenIfNeeded()
.forPath(parentNodePath);
} catch (Exception e) {
System.out.println("Delete parentNode failed, znode : " + parentNodePath);
e.printStackTrace();
}
}
/**
* 更新一个子节点
*/
public void setNodeDate(String nodePath, byte[] nodeData) {
try {
client.setData().forPath(nodePath, nodeData);
} catch (Exception e) {
System.out.println("Update data failed, znode : " + nodePath);
e.printStackTrace();
}
}
/**
* 获取一个子节点数据
*/
public byte[] getNodeData(String nodePath) {
byte[] data = null;
try {
data = client.getData().forPath(nodePath);
} catch (Exception e) {
System.out.println("Get data failed, znode : " + nodePath);
e.printStackTrace();
}
return data;
}
/**
* 获取一个父节点下所有子节点路径
*/
public List<String> getParentNodePath(String parentNodePath) {
List<String> list = new ArrayList<String>();
try {
list = client.getChildren().forPath(parentNodePath);
} catch (Exception e) {
System.out.println("Get children nodePath failed, znode : " + parentNodePath);
e.printStackTrace();
}
return list;
}
/**
* 判断当前节点是否存在
*/
public boolean nodePathExists(String nodePath) {
try {
Stat stat = client.checkExists().forPath(nodePath);
if (stat != null) {
return true;
}
} catch (Exception e) {
System.out.println("Get nodePath stat failed, znode : " + nodePath);
e.printStackTrace();
}
return false;
}
}
- 客户端的使用测试
import org.apache.commons.lang.StringUtils;
import org.apache.zookeeper.CreateMode;
import java.io.Serializable;
import java.util.List;
public class WorkerRegister implements Serializable {
public static void main(String[] args) {
String zkAddress = "localhost:2181";
CuratorClient zkClient = new CuratorClient(zkAddress);
//注册当前节点信息
String path = "/test/node1";
String data = "info:hello";
zkClient.createNode(path, data.getBytes(), CreateMode.EPHEMERAL);
//获取当前节点信息
byte[] nodeData = zkClient.getNodeData(path);
System.out.println("nodeData : " + new String(nodeData));
//更新当前节点信息
data = "info:world";
zkClient.setNodeDate(path, data.getBytes());
//获取父节点下所有子节点路径
List<String> nodePaths = zkClient.getParentNodePath("/test");
System.out.println(StringUtils.join(nodePaths, ","));
}
}
测试结果如下所示:
nodeData : info:hello
node1