maven依赖:
一开始引入的是最新4.0的发现创建节点总是报错,是我zk版本比较低的原因。所以换了个低版本的curator。
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.11.1</version>
</dependency>
节点创建和监听器API使用:
public class ZKTest {
private static final String ZK_ADDRESS = "localhost:2181";
private static final String ZK_PATH = "todd/t4";
CuratorFramework zkclient=null;
/**
* 两种建立连接的方式:项目中往往使用这一种
* @throws Exception
*/
@Before
public void init() throws Exception {
System.out.println("init..");
/**
* 未加权限设置:
* connectString:连接字符串中间用分号隔开,
* sessionTimeoutM:ssession过期时间,
* connectionTimeoutMs:连接超时时间,
* retryPolicyc:连接重试策略,
* namespace:操作的目录地址
*/
// 重连策略:每1一秒重试一次,最大重试次数3次
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
zkclient = CuratorFrameworkFactory.builder()
.connectString(ZK_ADDRESS)
.sessionTimeoutMs(50000)
.retryPolicy(retryPolicy)
.namespace(ZK_PATH)
.build();
zkclient.start();
}
@After
public void after(){
//zkclient.close();
}
/**
* 查看节点是否存在
*/
public boolean isExisted(final String path) {
try {
return null != zkclient.checkExists().forPath(path);
} catch (Exception e) {
System.out.println("error");
return false;
}
}
/**
* 创建节点(默认:持久):永久存在
* @param path
* @param value utf-8格式
* @throws Exception
*/
public void createNode(String path,String value) throws Exception{
if(isExisted(path)){
this.setData(path, value);
}else{
zkclient.create()
.creatingParentsIfNeeded() //如果path的父目录不存在,则同时穿件父目录
.forPath(path,value.getBytes(Charset.forName("UTF-8")));
}
}
/**
* 创建临时节点:客户端退出时自动删除
* @param path
* @param value
* @throws Exception
*/
public void createEphemeral(String path, String value) throws Exception {
zkclient.create()
.creatingParentsIfNeeded()
.withMode(CreateMode.EPHEMERAL)
.forPath(path, value.getBytes(Charset.forName("UTF-8")));
}
/**
* 创建临时顺序节点
* @param path
* @param value
* @return
* @throws Exception
*/
public String createEphemeralSequential( String path,String value) throws Exception {
return zkclient.create()
.withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
.forPath(path, value.getBytes(Charset.forName("UTF-8")));
}
/**
* 创建持久顺序节点:
* @param path
* @param value
* @return
* @throws Exception
*/
public String createPersistentSequentia(String path,String value) throws Exception{
return zkclient.create()
.withMode(CreateMode.PERSISTENT_SEQUENTIAL)
.forPath(path, value.getBytes(Charset.forName("UTF-8")));
}
/**
* 为节点赋值:
* @param path
* @param value
* @throws Exception
*/
public void setData(String path,String value) throws Exception {
zkclient.setData().forPath(path, value.getBytes(Charset.forName("UTF-8")));
}
/**
* 删除节点
* @param path
* @throws Exception
*/
public void delete(String path) throws Exception {
zkclient.delete().forPath(path);
}
/**
* 获取节点数据
* @param path
* @return
* @throws Exception
*/
public String getNodeData(String path) throws Exception{
return new String(zkclient.getData().forPath(path),Charset.forName("UTF-8"));
}
/**
* 获取path的命名空间-当前路径前缀("todd/t4")
* @param path
* @return
* @throws Exception
*/
public String getNameSpace(String path) throws Exception{
return zkclient.getNamespace();
}
/**
* 获取节点的孩子节点
* @param path 当key为 '/'时返回的是命名空间下根节点列表
* @return
* @throws Exception
*/
public List<String> getChildrenKeys(String path) throws Exception {
List<String> result = zkclient.getChildren().forPath(path);
Collections.sort(result, new Comparator<String>() {
@Override
public int compare(final String o1, final String o2) {
return o2.compareTo(o1);
}
});
return result;
}
/**
* 递归删除节点.若不递归删除,则该路径下包含子节点则报非空异常
* @param path
* @throws Exception
*/
public void delNode(String path) throws Exception {
if (this.isExisted(path)) {
zkclient.delete()
.deletingChildrenIfNeeded()
.forPath(path);
}
}
/*===================节点监听:有三种方式 使用Cache==========================*/
/**
* Path Cache:监视一个路径下--孩子结点的创建 、删除、结点数据的更新,产生的事件会传递给注册的PathChildrenCacheListener。
* Node Cache:监视一个结点的创建、更新、删除,并将结点的数据缓存在本地。
* Tree Cache:Path Cache和Node Cache的"合体",监视路径下的创建、更新、删除事件,并缓存路径下所有孩子结点的数据。
*/
/**
* 子节点监听: 删除节点后不在监听事件变化
* @param path
* @throws Exception
*/
private void addChildWatcher(String path) throws Exception{
PathChildrenCache childrenCache = new PathChildrenCache(zkclient,path,true);
PathChildrenCacheListener childrenCacheListener = new PathChildrenCacheListener() {
@Override
public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
System.out.println("开始进行事件分析:-----");
ChildData data = event.getData();
switch (event.getType()) {
case CHILD_ADDED:
System.out.println("CHILD_ADDED:"
+ data.getPath()
+" 数据:"
+ new String(data.getData(), Charset.forName("UTF-8")));
break;
case CHILD_REMOVED:
System.out.println("CHILD_REMOVED : "
+ data.getPath()
+" 数据:"
+ new String(data.getData(), Charset.forName("UTF-8")));
break;
case CHILD_UPDATED:
System.out.println("CHILD_UPDATED : "
+ data.getPath()
+" 数据:"
+ new String(data.getData(), Charset.forName("UTF-8")));
break;
default:
break;
}
}
};
childrenCache.getListenable().addListener(childrenCacheListener);
System.out.println("Register zk watcher successfully!");
childrenCache.start(StartMode.POST_INITIALIZED_EVENT);
}
/**
* 监听节点的变化: 节点的创建、数据变化。删除节点不发生事件监听。删除节点重新建立发生事件监听。
* @param path
* @throws Exception
*/
private void addNodeWatcher(String path) throws Exception{
final NodeCache dataWatch = new NodeCache(zkclient, path);
dataWatch.getListenable().addListener(new NodeCacheListener() {
@Override
public void nodeChanged() throws Exception {
System.out.println("path : "+dataWatch.getCurrentData().getPath());
System.out.println("data : "+new String(dataWatch.getCurrentData().getData()));
}
});
dataWatch.start();
}
/**
* 监听节点和子节点变化:删除节点再次创建--继续监听
* @param path
* @throws Exception
*/
private void addNodeAndChildWatcher(String path) throws Exception{
//设置节点的cache
TreeCache treeCache = new TreeCache(zkclient, path);
//设置监听器和处理过程
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(), Charset.forName("UTF-8")));
break;
case NODE_REMOVED:
System.out.println("NODE_REMOVED : "
+ data.getPath()
+" 数据:"
+ new String(data.getData(), Charset.forName("UTF-8")));
break;
case NODE_UPDATED:
System.out.println("NODE_UPDATED : "
+ data.getPath()
+" 数据:"
+ new String(data.getData(), Charset.forName("UTF-8")));
break;
default:
break;
}
}else{
System.out.println( "data is null : "+ event.getType());
}
}
});
//开始监听
treeCache.start();
}
@Test
public void test01() throws Exception{
//boolean existed = isExisted("/zktest");
//createNode("/zktest01","x");
//createEphemeral("/linshi02","lishi");
//System.out.println(createEphemeralSequential("/testsghy","lishi"));
//System.out.println(createPersistentSequentia("/testsghy","aa"));
//setData("/zktest01","test11111");
//delete("/zktest01");
//System.out.println(getNodeData("/zktest01"));
//System.out.println(getNameSpace("/zktest01"));
// List<String> childrenKeys = getChildrenKeys("/");
// for(String key:childrenKeys){
// System.out.println(key);
// }
//delNode("/zktest02");
//addNodeWatcher("/zktest02");
//addChildWatcher("/zktest02");
addNodeAndChildWatcher("/zktest02");
Thread.sleep(500000);
}
}