2.1. public ZkClient(String serverstring)
2.2. public ZkClient(String zkServers, int connectionTimeout)
2.3. public ZkClient(String zkServers, int sessionTimeout, int connectionTimeout)
2.4. public ZkClient(String zkServers, int sessionTimeout, int connectionTimeout, ZkSerializer zkSerializer)
2.5. public ZkClient(IZkConnection connection)
2.6. public ZkClient(IZkConnection connection, int connectionTimeout)
2.7. public ZkClient(IZkConnection zkConnection, int connectionTimeout, ZkSerializer zkSerializer)
public class ZkConnection implements IZkConnection {
/** 默认的session超时时间为30 000毫秒 */
private static final int DEFAULT_SESSION_TIMEOUT = 30000;
// zookeeper 引用
private ZooKeeper _zk = null;
// 定义锁对象
private Lock _zookeeperLock = new ReentrantLock();
// 连接zookeeper字符串
private final String _servers;
private final int _sessionTimeOut;
// 构造函数
public ZkConnection(String zkServers) {
this(zkServers, DEFAULT_SESSION_TIMEOUT);
}
public ZkConnection(String zkServers, int sessionTimeOut) {
_servers = zkServers;
_sessionTimeOut = sessionTimeOut;
}
/** 连接zookeeper方法,注册wathcer */
public void connect(Watcher watcher) {
// 加锁,保证只有一个客户端连接上即可
_zookeeperLock.lock();
try {
if (_zk != null) {
throw new IllegalStateException("zk client has already been started");
}
try {
// 原生的创建zookeeper连接
_zk = new ZooKeeper(_servers, _sessionTimeOut, watcher);
} catch (IOException e) {
throw new ZkException("Unable to connect to " + _servers, e);
}
} finally {
_zookeeperLock.unlock();
}
}
/** 关闭zookeeper连接 **/
public void close() throws InterruptedException {
_zookeeperLock.lock();
try {
if (_zk != null){
_zk.close();
_zk = null;
}
} finally {
_zookeeperLock.unlock();
}
}
// 创建节点
public String create(String path, byte[] data, CreateMode mode) throws KeeperException, InterruptedException {
return _zk.create(path, data, Ids.OPEN_ACL_UNSAFE, mode);
}
// 删除节点
public void delete(String path) throws InterruptedException, KeeperException {
_zk.delete(path, -1);
}
// 检查节点是否存在
public boolean exists(String path, boolean watch) throws KeeperException, InterruptedException {
return _zk.exists(path, watch) != null;
}
// 获取当前节点的子节点列表
public List getChildren(final String path, final boolean watch) throws KeeperException, InterruptedException {
return _zk.getChildren(path, watch);
}
// 读取节点数据内容
public byte[] readData(String path, Stat stat, boolean watch) throws KeeperException, InterruptedException {
return _zk.getData(path, watch, stat);
}
// 更新节点数据内容
public void writeData(String path, byte[] data) throws KeeperException, InterruptedException {
writeData(path, data, -1);
}
// 更新节点数据内容,附带版本信息
public void writeData(String path, byte[] data, int version) throws KeeperException, InterruptedException {
_zk.setData(path, data, version);
}
// 获取zookeeper状态
public States getZookeeperState() {
return _zk != null ? _zk.getState() : null;
}
public ZooKeeper getZookeeper() {
return _zk;
}
@Override
public long getCreateTime(String path) throws KeeperException, InterruptedException {
Stat stat = _zk.exists(path, false);
if (stat != null) {
return stat.getCtime();
}
return -1;
}
@Override
public String getServers() {
return _servers;
}
}
// 创建持久化节点,内容默认为空
2.1. public void createPersistent(String path)
// 父节点不存在,可以先创建父节点,再创建子节点,内容默认为空
2.2. public void createPersistent(String path, boolean createParents)
// 创建带有数据的节点
2.3. public void createPersistent(String path, Object data)
// 创建持久化顺序节点
2.4. public String createPersistentSequential(String path, Object data)
// 创建临时节点,数据默认为空
2.5. public void createEphemeral(final String path)
// 创建临时节点,指定数据内容
2.6. public void createEphemeral(final String path, final Object data)
// 创建临时顺序节点
2.7. public String createEphemeralSequential(final String path, final Object data)
// 根据指定模式创建节点
2.8. public String create(final String path, Object data, final CreateMode mode)
// 读取当前节点数据内容,节点不存在抛出异常
1.1. public Object> T readData(String path)
// 读取当前节点数据内容,returnNullIfPathNotExists参数表明节点不存在不会抛出异常
1.2. public Object> T readData(String path, boolean returnNullIfPathNotExists)
// 传入状态数值,服务端返回最新的状态
1.3. public Object> T readData(String path, Stat stat)
1.更新节点内容主要是封装了2个方法,
// 更新数据内容
1.1. public void writeData(String path, Object object)
// 根据传入的期望版本数值,更新节点数据内容,类似于CAS方式
1.2. public void writeData(final String path, Object datat, final int expectedVersion)
1.zkClient提供了三种事件监听接口,分别是:
1.1. IZkDataListener :当前节点数据内容或版本发生变化或者当前节点被删除,触发当前接口
1.2. IZkChildListener: 节点列表变化事件监听,即当前节点的子节点发生变化(删除)或子节点列表发生变化(新增或删除),触发当前接口
1.3. IZkStateListener:zookeeper连接状态发生变化时,触发该接口,这个在zkClient连接zookeeper时,用到比较多。
2. IZkDataListener
/**详述:client向某个节点注册该listener后,如果该节点的数据内容发生变化,则服务 端通过该接口通知客户端。还有另外一种情况,如果当前节点不存在时,如果创建了该节点,也会发生通知
**/
public interface IZkDataListener {
/**dataPath:当前数据节点
** data:服务端传递过来最新节点数据内容,不需要重新去服务端重新获取
*/
public void handleDataChange(String dataPath, Object data) throws Exception;
/**删除当前节点,触发该接口通知。此时,dataPath即当前节点路径*/
public void handleDataDeleted(String dataPath) throws Exception;
}
// 调用该方法可以将listener注册到某一个节点,监听某一个节点数据内容的变化
3. 1. public void subscribeDataChanges(String path, IZkDataListener listener)
// 调用该方法可以当前节点path上的监听解除
3. 2. public void unsubscribeDataChanges(String path, IZkDataListener dataListener)
3.3. 使用方式
/**
* IZkDataListener接口主要有两个方法:
* ---handleDataChange(dataPath,data)
* ---handleDataDeleted(dataPath)
* @param parentPath
*/
public void listenDataChange(String currentPath){
zkClient.subscribeDataChanges(currentPath,new IZkDataListener(){
public void handleDataChange(String dataPath, Object data)
throws Exception {
System.out.println("dataPath="+dataPath+",data = "+data);
}
public void handleDataDeleted(String dataPath) throws Exception {
System.out.println("deleted node = "+dataPath);
}});
}
1. public interface IZkChildListener {
/**
* Called when the children of the given path changed.
* @param parentPath:父节点,即监听的是parentPath子节点
* @param currentChilds
* parentpath删除,返回null.存在,返回最新的子节点列表,不需要重新去获取最新的子节点列表
*/
public void handleChildChange(String parentPath, List currentChilds) throws Exception;
}
5.注册IZkChildListener
// 注册节点变化listener
5.1 public List<String> subscribeChildChanges(String path, IZkChildListener listener)
// 解除节点变化listener
5.2 public void unsubscribeChildChanges(String path, IZkChildListener childListener)
5.3 /**
* parentPath:当前父节点
* 服务端发生如下变化时,会通知客户端
* ---新增子节点
* ---删除子节点
* ---删除子节点
*/
public void listenChildNodeChange(String parentPath){
zkClient.subscribeChildChanges(parentPath, new IZkChildListener(){
public void handleChildChange(String parentPath,
List<String> currentChilds) throws Exception {
System.out.println("父节点是 : "+parentPath);
for(String child:currentChilds){
System.out.println("子节点路径为-->"+child);
}
}});
}