Curator是Zookeeper开源的客户端框架,封装了很多API,使用起来非常的方便,直接进入正题,讲解如何使用。
一、客户端创建
使用静态工厂方式进行创建,connectionInfo为Zookeeper地址,例如:127.0.0.1:2181
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.newClient(connectionInfo, retryPolicy);
client.start();
二、CuratorFramework常用API
对上述接口进行了二次封装,写了个ZKClient工具类
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.transaction.CuratorTransaction;
import org.apache.curator.framework.recipes.cache.*;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
/**
* Created by wzj on 2018/5/4.
*/
public class ZKClient
{
/**
* 客户端
*/
private CuratorFramework client = null;
/**
* 构造方法
*
* @param connectionInfo zk主机
*/
public ZKClient(String connectionInfo)
{
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
client = CuratorFrameworkFactory.newClient(connectionInfo, retryPolicy);
client.start();
}
/**
* 创建节点
*
* @param path 路径
* @param createMode 节点类型
* @param data 节点数据
* @return 是否创建成功
*/
public boolean crateNode(String path, CreateMode createMode, String data)
{
try
{
client.create().withMode(createMode).forPath(path, data.getBytes());
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
return true;
}
/**
* 删除节点
*
* @param path 路径
* @return 删除结果
*/
public boolean deleteNode(String path)
{
try
{
client.delete().forPath(path);
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
return true;
}
/**
* 删除一个节点,并且递归删除其所有的子节点
*
* @param path 路径
* @return 删除结果
*/
public boolean deleteChildrenIfNeededNode(String path)
{
try
{
client.delete().deletingChildrenIfNeeded().forPath(path);
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
return true;
}
/**
* 判断节点是否存在
*
* @param path 路径
* @return true-存在 false-不存在
*/
public boolean isExistNode(String path)
{
try
{
Stat stat = client.checkExists().forPath(path);
return stat != null ? true : false;
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
}
/**
* 判断节点是否是持久化节点
* @param path 路径
* @return 2-节点不存在 | 1-是持久化 | 0-临时节点
*/
public int isPersistentNode(String path)
{
try
{
Stat stat = client.checkExists().forPath(path);
if (stat == null)
{
return 2;
}
if (stat.getEphemeralOwner() > 0)
{
return 1;
}
return 0;
}
catch (Exception e)
{
e.printStackTrace();
return 2;
}
}
/**
* 获取节点数据
*
* @param path 路径
* @return 节点数据,如果出现异常,返回null
*/
public String getNodeData(String path)
{
try
{
byte[] bytes = client.getData().forPath(path);
return new String(bytes);
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}
/**
* 注册节点数据变化事件
*
* @param path 节点路径
* @param nodeCacheListener 监听事件
* @return 注册结果
*/
public boolean registerWatcherNodeChanged(String path, NodeCacheListener nodeCacheListener)
{
NodeCache nodeCache = new NodeCache(client, path, false);
try
{
nodeCache.getListenable().addListener(nodeCacheListener);
nodeCache.start(true);
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
return true;
}
/**
* 更新节点数据
*
* @param path 路径
* @param newValue 新的值
* @return 更新结果
*/
public boolean updateNodeData(String path, String newValue)
{
//判断节点是否存在
if (!isExistNode(path))
{
return false;
}
try
{
client.setData().forPath(path, newValue.getBytes());
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
return true;
}
/**
* 开启事务
*
* @return 返回当前事务
*/
public CuratorTransaction startTransaction()
{
return client.inTransaction();
}
}
三、事务处理
增删改查每一个节点都是一个原子操作,一系列的原子操作就是一个事务。
在ZKClient增加获取事务方法
public CuratorTransaction startTransaction()
{
return client.inTransaction();
}
测试,构造三个原子操作
zkClient.startTransaction().create().forPath("/henan")
.and().create().forPath("/henan/zhengzhou")
.and().delete().forPath("/ads")
.and().commit();
只有三个原子操作都成功,三个操作才能最终执行。
四、注册节点监听
将Zookeeper作为配置中心的时候,最常用的是监听节点数据的变动。
在ZKClient添加注册节点变动方法。
/**
* 注册节点数据变化事件
*
* @param path 节点路径
* @param nodeCacheListener 监听事件
* @return 注册结果
*/
public boolean registerWatcherNodeChanged(String path, NodeCacheListener nodeCacheListener)
{
NodeCache nodeCache = new NodeCache(client, path, false);
try
{
nodeCache.getListenable().addListener(nodeCacheListener);
nodeCache.start(true);
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
return true;
}
测试监听/zhejiang节点数据变动
Demo代码下载链接:https://download.youkuaiyun.com/download/u010889616/10394855