它是一个为分布式应用提供一致性服务的软件。
Zookeeper 作为一个分布式的服务框架,主要用来解决分布式集群中应用系统的一致性问题,它能提供基于类似于文件系统的目录节点树方式的数据存储, Zookeeper 作用主要是用来维护和监控存储的数据的状态变化,通过监控这些数据状态的变化,从而达到基于数据的集群管理。
java 操作
//创建zk连接
ZooKeeper zk = new ZooKeeper(CONNETTION_ADDR, SESSION_TIMEOUT, new Watcher() {
public void process(WatchedEvent event) {
// 获取时间的状态
//通知状态
KeeperState keeperState = event.getState();
//事件类型
EventType tventType = event.getType();
// 如果是建立连接
if (KeeperState.SyncConnected == keeperState) {
if (EventType.None == tventType) {
System.out.println("创建zk连接");
}
}
}
});
//创建zk节点
zk.create("/zk", "testZookeeper".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//使用zkclient包的方式
ZkClient zkClient=new ZkClient("host");
zkClient.createEphemeral("path");
监听
package com.zk.watcher;
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
public class ZookeeperWatcher implements Watcher {
// 集群连接地址
private static final String CONNECT_ADDRES = "127.0.0.1:2181";
// 会话超时时间
private static final int SESSIONTIME = 2000;
// 信号量,zk连接异步,用于阻塞,保证所有的操作都在zk创建连接成功以后再执行
private static final CountDownLatch countDownLatch = new CountDownLatch(1);
private ZooKeeper zk;
public void createConnection(String connectAddres, int sessionTimeOut) {
try {
zk = new ZooKeeper(connectAddres, sessionTimeOut, this);
System.out.println("LOG" + "zk 开始启动连接服务器....");
countDownLatch.await();
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean createPath(String path, String data) {
try {
this.exists(path, true);
// 创建持久节点
this.zk.create(path, data.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("LOG" + "节点创建成功, Path:" + path + ",data:" + data);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 判断指定节点是否存在 不存在该节点返回null
*
* @param path
* 节点路径
*/
public Stat exists(String path, boolean needWatch) {
try {
return this.zk.exists(path, needWatch);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public boolean updateNode(String path, String data) throws KeeperException, InterruptedException {
exists(path, true);
this.zk.setData(path, data.getBytes(), -1);
return false;
}
public void process(WatchedEvent watchedEvent) {
// 获取事件状态
KeeperState keeperState = watchedEvent.getState();
// 获取事件类型
EventType eventType = watchedEvent.getType();
// zk 路径
String path = watchedEvent.getPath();
// 判断是否建立连接
if (KeeperState.SyncConnected == keeperState) {
// 如果当前状态已经连接上了 SyncConnected:连接,AuthFailed:认证失败,Expired:失效过期,
// ConnectedReadOnly:连接只读,Disconnected:连接失败
if (EventType.None == eventType) {
// 如果建立建立成功,让后程序往下走
System.out.println("LOG" + "zk 建立连接成功!");
countDownLatch.countDown();
} else if (EventType.NodeCreated == eventType) {
System.out.println("LOG" + "事件通知,新增node节点" + path);
} else if (EventType.NodeDataChanged == eventType) {
System.out.println("LOG" + "事件通知,当前node节点" + path + "被修改....");
} else if (EventType.NodeDeleted == eventType) {
System.out.println("LOG" + "事件通知,当前node节点" + path + "被删除....");
}
}
}
public static void main(String[] args) throws KeeperException, InterruptedException {
ZookeeperWatcher zkClientWatcher = new ZookeeperWatcher();
zkClientWatcher.createConnection(CONNECT_ADDRES, SESSIONTIME);
zkClientWatcher.createPath("/createNode", "pa-644064");
// 修改createNode节点
zkClientWatcher.updateNode("/createNode", "7894561");
}
}
节点注册和监听
package com.zk.distributed;
import java.util.concurrent.CountDownLatch;
import org.I0Itec.zkclient.IZkDataListener;
public class ZkDistributeLock extends ZkDistributedAbstractLock {
@Override
Boolean tryGetLock() {
try {
zkClient.createEphemeral(PATH);
return true;
} catch (Exception e) {
return false;
}
}
@Override
void waitUnLock() {
// 使用事件监听,获取到节点被删除,zookeeper上节点有什么变化都可以感知到
IZkDataListener iZkDataListener = new IZkDataListener() {
// 当节点被删除
public void handleDataDeleted(String dataPath) throws Exception {
if (countDownLatch != null) {
// 唤醒
countDownLatch.countDown();
}
}
// 当节点发生改变
public void handleDataChange(String dataPath, Object data) throws Exception {
}
};
// 注册节点信息
zkClient.subscribeDataChanges(PATH, iZkDataListener);
//检测是否存在该节点信息
if (zkClient.exists(PATH)) {
// 创建信号量
countDownLatch = new CountDownLatch(1);
try {
// 等待
countDownLatch.await();
} catch (Exception e) {
}
}
// 删除事件通知
zkClient.unsubscribeDataChanges(PATH, iZkDataListener);
}
}