一、环境准备及创建会话实例
-
JAR包
使用JAVA API调用ZooKeeper时必须要导入对应的jar包
对应的jar包:ZooKeeper-3.x.x.jar(其中的x需要依据版本而定。
注意:使用3.4.14版本的ZooKeeper时,如何使用3.4.14的jar包,创建连接时需要把session超时时间设置长一点否则会报错,改用3.4.10版本的jar包则无此问题)
在lib目录下的jar包也是需要导入的
2. 创建会话实例
需要访问ZooKeeper的第一步是需要先保证可以创建会话实例
创建会话实例的方法
ZooKeeper(String connectString,int sessionTimeout,Watcher watcher)
connectString:表示连接到哪一个Zookeeper,如192.168.2.2:2181
sessionTimeout:表示会话过期时间,单位是毫秒
watcher:通过注册Watcher来实现对节点的状态变化监听
关于ZooKeeper的构造方法还有如下几个:
ZooKeeper(String connectString,int sessionTimeout,Watcher watcher,boolean canBeReadOnly)
ZooKeeper(String connectString,int sessionTimeout,Watcher watcher,long sessionId,boolean canBeReadOnly)
ZooKeeper(String connectString,int sessionTimeout,Watcher watcher,long sessionId,byte[] sessionPasswd,boolean canBeReadOnly)
canBeReadOnly:表示当前会话是否支持read-only
sessionId:表示会话的ID
sessionPasswd:密钥
关于watcher
watcher是org.apache.Zookeeper.Watcher类型的对象,当客户端和服务器建立连接后会调用Watcher中的process方法,这个方法中会有一个WatchedEvent类型的参数,它用来标识发生了哪一种事件
WatchedEvent主要包含以下两个方面的信息:
watchedEvent.getState():取得与服务器连接状态,这里的连接状态包含(SyncConnected、Disconnected、connectedReadOnly、AuthFailed等)
watchedEvent.getType():取得节点事件类型,通过它可以获得具体的事件类型,这里事件类型的取值包含(None、NodeCreated、NodeDeleted、 NodeDataChanged、NodeChildrenChanged)
注意:Watcher通知是一次性的,当一旦触发一次通知后,这个Watcher就无效了,客户端需要再次注册Watcher,否则无法再次监听到节点的状态变化
二、使用JAVA API调用ZooKeeper
使用JAVA API创建节点
public class ZooKeeperDemo implements Watcher{
private static final int SESSION_TIMEOUT = 3000;
public static ZooKeeper ZooKeeper;
public static void main(String[] args) {
String path = "/mynode";
try {
ZooKeeper = new ZooKeeper("192.168.2.2:2181",SESSION_TIMEOUT,new ZooKeeperDemo());
ZooKeeper.exists(path,true);
ZooKeeper.create(path,"mycontent 1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void process(WatchedEvent event) {
if(Event.KeeperState.SyncConnected == event.getState()){
if(Event.EventType.NodeCreated == event.getType()){
//创建成功时在此处进行回调
System.out.println("node创建成功!");
try {
ZooKeeper.exists(event.getPath(),true);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
创建节点语句:
ZooKeeper.create(path,"mycontent 1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
第一个参数:path,是一个局部变量“/mynode”
第二个参数:"mycontent 1".getBytes(),指的是创建节点的数据值
第三个参数:
ZooDefs.Ids.
OPEN_ACL_UNSAFE
,指的是这个节点的访问权限为任何人可以访问
第四个参数:CreateMode.PERSISTENT,指的是创建节点的类型,这里指的是在会话重启后节点仍然存在
节点的创建、取值、修改、删除操作
public class ZookeeperDemo01 implements Watcher {
//定义sessioTimeout常量
private static final int SESSION_TIMEOUT = 30000;
public static ZooKeeper zooKeeper;
public static void main(String[] args) {
createNode("/zknode1");
getContent("/zknode1");
setContent("/zknode1","你好!");
getContent("/zknode1");
deleteNode("/zknode1");
closeConnect(zooKeeper);
}
@Override
public void process(WatchedEvent watchedEvent) {
if (Event.KeeperState.SyncConnected == watchedEvent.getState()) {
if (Event.EventType.NodeCreated == watchedEvent.getType()) {
//创建节点的消息通知
System.out.println("创建节点成功! 时间:" + new SimpleDateFormat("yyyy-mm-dd HH:mm:ss").format(new Date()));
try {
zooKeeper.exists(watchedEvent.getPath(), true);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else if(Event.EventType.NodeDeleted == watchedEvent.getType()){
try {
zooKeeper.exists(watchedEvent.getPath(),true);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("节点被删除! 时间:" + new SimpleDateFormat("yyyy-mm-dd HH:mm:ss").format(new Date()));
} else if(Event.EventType.NodeDataChanged == watchedEvent.getType()){
try {
zooKeeper.exists(watchedEvent.getPath(),true);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("节点被修改! 时间:" + new SimpleDateFormat("yyyy-mm-dd HH:mm:ss").format(new Date()));
}
}
}
/**
* 创建节点
*
* @param path
*/
public static void createNode(String path) {
try {
zooKeeper = new ZooKeeper("192.168.2.4:2181", SESSION_TIMEOUT, new ZookeeperDemo01());
zooKeeper.exists(path, true);
//创建节点
zooKeeper.create(path, "xiesheng".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取节点的内容
*
* @param path
* @return
*/
public static String getContent(String path) {
try {
if (zooKeeper == null) {
zooKeeper = new ZooKeeper("192.168.2.4:2181", SESSION_TIMEOUT, new ZookeeperDemo01());
}
byte[] rb = zooKeeper.getData(path, null, null);
System.out.println("获取节点【" + path + "】的内容为:" + new String(rb));
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 设置节点的内容
* @param path
* @param content
*/
public static void setContent(String path,String content) {
try {
if (zooKeeper == null) {
zooKeeper = new ZooKeeper("192.168.2.4:2181", SESSION_TIMEOUT, new ZookeeperDemo01());
}
zooKeeper.setData(path, content.getBytes(), -1);
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 删除节点
* @param path
*/
public static void deleteNode(String path){
try {
if (zooKeeper == null) {
zooKeeper = new ZooKeeper("192.168.2.4:2181", SESSION_TIMEOUT, new ZookeeperDemo01());
}
zooKeeper.delete(path,-1);
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 关闭连接
* @param zooKeeper
*/
public static void closeConnect(ZooKeeper zooKeeper){
if(zooKeeper == null){
System.out.println("未连接,无需关闭!");
} else {
try {
zooKeeper.close();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("连接关闭成功!");
}
}
}
进行以上测试后控制台打印结果如下:
创建节点成功! 时间:2020-13-04 11:13:11
获取节点【/zknode1】的内容为:xiesheng
节点被修改! 时间:2020-13-04 11:13:17
获取节点【/zknode1】的内容为:你好!
节点被删除! 时间:2020-13-04 11:13:23
连接关闭成功!