Appearance
Zookeeper管阀提供了java客户端操作Zookeeper的API,但是并不好用,我们使用大神封装好的ZKClient客户端操作Zookeeper,一篇文章即可上手。
xml
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
初始化ZClient
就两个参数,ip地址加端口号以及连接超时时间。
java
ZkClient zkClient = new ZkClient("192.168.31.76:2181", 50000);
创建节点
createParents用于创建节点,支持直接写路径递归创建子节点,且节点内容可以传任意类型数据,可以自定义内容的序列化和反序列化。在没指定zkSerializer时,默认使用java自动的序列化和反序列化
java
package cn.lxm.attendance.controller;
import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.IZkConnection;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.ZkConnection;
import org.apache.zookeeper.CreateMode;
import java.util.List;
public class ZkClientTest {
private static final String PATH = "/xk857/test";
static ZkClient zkClient = new ZkClient("192.168.31.76:2181",50000);
public static void main(String[] args) throws InterruptedException {
createNode();
List<String> children = zkClient.getChildren("/");
System.out.println(children);
}
// 创建node
public static void createNode(){
// 创建一个永久的node节点a
zkClient.createPersistent("/a");
// 创建一个永久性node节点b,和原生API相似直接传递数据进去,CreateMode有四种取值
zkClient.create("/b","这里是内容", CreateMode.PERSISTENT);
// 创建一个永久性node节点c/cc,true代表可以递归创建
zkClient.createPersistent("/c/cc",true);
// 创建永久性node节点d,里面内容为‘内容d’
zkClient.createPersistent("/d","内容d");
// 创建一个临时节点f
zkClient.createEphemeral("/f");
// 创建一个临时节点g,内容为 ‘内容g’
zkClient.createEphemeral("/g","内容g");
// 创建一个 递增序号 临时节点h
zkClient.createEphemeralSequential("/h","内容h");
// 创建一个 递增序号 的永久节点i
zkClient.createPersistentSequential("/i","内容i");
}
}
- CreateMode
PERSISTENT
:持久节点。如果节点不存在,则创建该节点;如果节点已经存在,则抛出异常。EPHEMERAL
:临时节点。如果节点不存在,则创建该节点;如果节点已经存在,则删除该节点和其所有子节点。EPHEMERAL_SEQUENTIAL
:顺序临时节点。与EPHEMERAL
类似,但如果节点已经存在,则在当前节点之后创建一个新节点。EPHEMERAL_ALLOFTHEABOVE
:以上三种节点类型的组合。即同时具有PERSISTENT
、EPHEMERAL
和EPHEMERAL_SEQUENTIAL
节点的特性
删除节点
deleteRecursive可以递归删除节点下所有的子节点
java
public static void deleteNode(){
// 删除节点c,以及节点c下面所有的子节点
zkClient.deleteRecursive("/c");
}
ZKClient注册监听
subscribeChildChanges
:在节点上加上一个listen监听事件,用来监听子节点的变化subscribeDataChanges
:监听当前节点上数据的变化;handleDataChange数据变化, handleDataDeleted节点数据被删除subscribeStateChanges
:监听zookeeper的状态
java
// 注册一个监听事件,subscribeChildChanges,通过使用listen方式来监听来达到消息广播效果,监听子节点变化
zkClient.subscribeChildChanges("/zz", new IZkChildListener() {
@Override
public void handleChildChange(String s, List<String> list) throws Exception {
System.out.println(">>>进入了handleChildChange");
System.out.println(">>>s = " + s);
System.out.println(">>>list = " + list);
}
});
// 注册一个监听事件,subscribeDataChanges 监听节点上数据的变化
zkClient.subscribeDataChanges("/zz", new IZkDataListener() {
@Override
public void handleDataChange(String dataPath, Object data) throws Exception {
System.out.println(">>> 进入了handleDataChange");
System.out.println(">>> dataPath = " + dataPath);
System.out.println(">>> data = " + data);
}
@Override
public void handleDataDeleted(String dataPath) throws Exception {
System.out.println(">>> 进入了handleDataDeleted");
System.out.println(">>> dataPath = " + dataPath);
}
});
// 监听zookeeper状态变化
zkClient.subscribeStateChanges(new IZkStateListener() {
@Override
public void handleStateChanged(Watcher.Event.KeeperState state) throws Exception {
System.out.println(">>> 进入了subscribeStateChanges");
System.out.println(">>> state = " + state);
}
@Override
public void handleNewSession() throws Exception {
System.out.println(">>> 进入了handleNewSession");
}
});
其他操作
- 返回PATH下的所有子节点:zkClient.getChildren(PATH);
- 写数据:zkClient.writeData(PATH, "456");
- 检查节点是否存在:zkClient.exists(PATH);