环境搭建
第一步:创建一个Maven工程,添加Maven依赖:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.13</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.11</version>
</dependency>
第二步:在resources目录下创建log4j.properties文件:
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
第三步:创建代码框架:
public class TestZK {
private String connStr = "hcslave1:2181,hcmaster:2181,hcslave2:2181";
private int sessionTimeout = 5000;
private ZooKeeper zk = null;
@Before
public void init() throws IOException {
//ip端口,连接超时时间,监听者
zk = new ZooKeeper(connStr, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
if (event.getState() == Event.KeeperState.SyncConnected) {
System.out.println("连接成功!");
}
// 收到事件通知后的回调函数(用户的业务逻辑)
System.out.println(event.getType() + "--" + event.getPath());
}
});
}
}
创建子节点
@Test
public void create() throws Exception {
String res = zk.create("/aa/a1", "aaaa1111".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(res);
}
@Test
public void createEphemeral() throws Exception {
String res = zk.create("/aa/a2", "aaaa2222".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println(res);
}
解释:
public String create(String path, byte[] data, List acl, CreateMode createMode)
其中:
- path:要创建的节点的路径
- data:要存放的节点的数据
- acl:节点权限,取值有:
- OPEN_ACL_UNSAFE:公开,无需权限模式
- CREATOR_ALL_ACL:创建者拥有全部的权限
- READ_ACL_UNSAFE:只读模式
- createMode:节点的类型/创建模式,取值有:
- PERSISTENT:持久节点
- PERSISTENT_SEQUENTIAL:持久节点并且顺序递增的
- EPHEMERAL:临时节点
- EPHEMERAL_SEQUENTIAL:临时节点,并且顺序递增的
设置节点数据
@Test
public void setData() throws Exception {
zk.setData("/aa/a1", "hc".getBytes(), 0);
}
第三个参数是数据版本号。如果不需要确认当前数据版本,可传入版本号为-1。
判断节点是否存在
@Test
public void exist() throws Exception {
Stat stat = zk.exists("/aa", false);
System.out.println(stat == null ? "不存在" : "存在");
}
获取节点数据
@Test
public void getDate() throws KeeperException, InterruptedException {
byte[] byteDate = zk.getData("/aa", null, null);
System.out.println(new String(byteDate));
}
参数:节点,监听者,节点的状态信息stat如时间戳等
删除数据
@Test
public void delete() throws KeeperException, InterruptedException {
zk.delete("/aa/a3", 1);//注意stat中的dataversion要一致,否则报错
}
若版本号传-1,则直接删除节点。
获取子节点
@Test
public void ls() throws Exception {
//参数:节点,监听者
List<String> list = zk.getChildren("/", null);
for (String s : list) {
System.out.println(s);
}
}
获取指定路径下的所有节点,包括子节点
@Test
public void lsAll() throws Exception {
ls("/");
}
public void ls(String path) throws Exception {
List<String> list = zk.getChildren(path, null);
if (list == null || list.isEmpty()) {
return;
}
for (String s : list) {
if (path.equals("/")) { //先输出孩子
ls(path + s);
} else {
ls(path + "/" + s);
}
}
}
获取节点并监听节点变化
@Test
public void watchChange1() throws Exception {
Stat stat = new Stat(); //状态
byte[] data = zk.getData("/aa", new Watcher() {
@Override
public void process(WatchedEvent event) {
if (event.getType() == Event.EventType.NodeDataChanged) {
System.out.println("节点数据改变了!");
}
}
}, stat);
System.out.println(new String(data));
Thread.sleep(50000);
}
zookeeper中的监听默认是一次性的。要想永久监听需要自己处理:
@Test
public void watchChange2() throws Exception {
Stat stat = new Stat(); //状态
final String path = "/aa";
byte[] data = zk.getData(path, new Watcher() {
@Override
public void process(WatchedEvent event) {
if (event.getType() == Event.EventType.NodeDataChanged) {
try {
byte[] res = zk.getData(path, this, stat);//设置可以反复监听
System.out.println("节点数据改变了 " + new String(res));
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
}
}
}, stat);
System.out.println(new String(data));
Thread.sleep(50000);
}
获取节点并监听节点删除
@Test
public void watchDelete() throws Exception {
String path = "/aa/a2";
Stat stat = new Stat(); //状态
byte[] data = zk.getData(path, new Watcher() {
@Override
public void process(WatchedEvent event) {
if (event.getType() == Event.EventType.NodeDeleted) {
System.out.println("节点数据删除了!");
}
}
}, stat);
System.out.println("****" + new String(data));
// 延时阻塞
Thread.sleep(Long.MAX_VALUE);
}
来源:CSDN
作者:梁云亮
链接:https://blog.csdn.net/lianghecai52171314/article/details/104745405