1.IDEA环境搭建
1)创建module
2)添加pom文件
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</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.5.7</version>
</dependency>
</dependencies>
3)添加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
2. 初始化zk客户端信息
package com.fengxq.zookeeper.demo;
import org.apache.zookeeper.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
public class ZookeeperClient {
/**
* 操作zookeeper客户端分3步:
* 1. 获取客户端连接对象
* 2. 业务操作
* 3. 关闭客户端连接对象
*/
private ZooKeeper zk;
@Before
public void init() throws IOException {
/**
* 1. connectionString : 连接zk服务集群的地址:"127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"
* 2. sessionTimeout:session过期时间,范围(4000~40000)毫秒
* 3. Watcher : 监听器对象,在连接zk时就要建立监听通道,用于后期随时得到zk通知
*
*/
String connectString = "hadoop102:2181, hadoop103:2181, hadoop104:2181";
int sessionTimeout = 100000;
// 1. 获取客户端连接对象
zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
System.out.println("客户端得到了zk通知!!!");
}
});
}
@After
public void close(){
try {
zk.close(); //3. 关闭客户端连接对象
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
3.创建子节点
/**
* 创建普通节点
*
* * @param path : 指定节点路径
* * the path for the node
* * @param data :给当前节点赋值
* * the initial data for the node
* * @param acl : 控制用户的可操作权限
* * the acl for the node
* * @param createMode :选择创建的节点类型
*/
@Test
public void testCreate() throws KeeperException, InterruptedException {
zk.create("/sanguo/liubei",
"刘备".getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT);
}
[zk: hadoop102:2181(CONNECTED) 18] get /sanguo/liubei
刘备
4.获取指定节点的子节点
/**
* 获取指定节点的子节点,不进行监控
*
* @throws KeeperException
* @throws InterruptedException
*/
@Test
public void testGetNoWatch() throws KeeperException, InterruptedException {
// 获取子节点,不进行监控
List<String> children = zk.getChildren("/sanguo", false);
for (String child : children) {
System.out.println(child);
}
}
zhaoyun0000000002
zhangfei
guanyu0000000000
liubei
5.获取指定节点的子节点并进行监控
/**
* 获取指定节点的子节点并进行监控
*
* @throws KeeperException
* @throws InterruptedException
*/
@Test
public void testGetWatch() throws KeeperException, InterruptedException {
// 获取子节点,进行监控
List<String> children = zk.getChildren("/sanguo", new Watcher() {
@Override
public void process(WatchedEvent event) {
System.out.println("监控节点/sanguo发送了变化:"+event);
}
});
for (String child : children) {
System.out.println(child);
}
Thread.sleep(Long.MAX_VALUE);
}
[zk: hadoop102:2181(CONNECTED) 19] delete /sanguo/zhaoyun0000000002
监控节点/sanguo发送了变化:WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/sanguo
6.判断节点是否存在
/**
* 判断节点是否存在
*/
@Test
public void testExists() throws KeeperException, InterruptedException {
Stat stat = zk.exists("/sanguo", false);
if(stat == null){
System.out.println("该节点/sanguo不存在");
}else{
System.out.println("stat****"+stat.toString());
}
}
7.获取指定节点的数据
/**
* 获取指定节点的数据
*/
@Test
public void testGetData() throws KeeperException, InterruptedException, UnsupportedEncodingException {
String path = "/sanguo";
Stat stat = zk.exists(path, false);
if(stat == null){
System.out.println("该节点/sanguo不存在");
}else{
// 获取内容
byte[] data = zk.getData(path, false, stat);
// 打印内容
System.out.println(new String(data, "utf-8"));
}
}
8.设置指定节点的数据
/**
* 设置指定节点的数据
*/
@Test
public void testSetData() throws KeeperException, InterruptedException, UnsupportedEncodingException {
String path = "/sanguo";
Stat stat = zk.exists(path, false);
if(stat == null){
System.out.println("该节点/sanguo不存在");
}else{
// 设置内容
zk.setData(path, "三国演义".getBytes(), stat.getVersion());
}
}
[zk: hadoop102:2181(CONNECTED) 24] get /sanguo
三国演义
9.删除空节点
/**
* 删除空节点
*/
@Test
public void testDelete() throws KeeperException, InterruptedException, UnsupportedEncodingException {
String path = "/sanguo/zhangfei";
Stat stat = zk.exists(path, false);
if(stat == null){
System.out.println("该节点"+path +"不存在");
}else{
// 删除空节点
zk.delete(path, stat.getVersion());
}
}
[zk: hadoop102:2181(CONNECTED) 26] ls /sanguo/zhangfei
[]
[zk: hadoop102:2181(CONNECTED) 27] ls /sanguo/zhangfei
Node does not exist: /sanguo/zhangfei
10.递归删除非空节点
/**
* 删除非空节点
*/
@Test
public void testDeleteAll() throws KeeperException, InterruptedException, UnsupportedEncodingException {
String path = "/sanguo";
deleteAll(path, zk);
}
/**
* 递归删除非空节点
* @param path
* @throws KeeperException
* @throws InterruptedException
*/
private void deleteAll(String path, ZooKeeper zk) throws KeeperException, InterruptedException {
Stat stat = zk.exists(path, false);
if(stat == null){
System.out.println("该节点"+path +"不存在");
}else{
List<String> children = zk.getChildren(path, false);
if(children.isEmpty()){
// 若是空节点,直接删除
zk.delete(path, stat.getVersion());
System.out.println("删除:"+path);
}else{
for (String child : children) {
// 递归调用
deleteAll(path+"/"+child, zk);
}
// 删除最外层的path节点
zk.delete(path, stat.getVersion());
System.out.println("删除:"+path);
}
}
}
客户端得到了zk通知!!!
删除:/sanguo/liubei/liuchan
删除:/sanguo/liubei
删除:/sanguo
客户端得到了zk通知!!!