Java客户端API操作zookeeper
首先创建项目添加zookeeper依赖
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.5.5</version>
</dependency>
zookeeper服务端端情况: /节点下有个/course节点,/course的值为helloworld;
使用Java客户端api查看/course数据:
通过org.apache.zookeeper.ZooKeeper#getDate()即可查看节点,其参数说明如下:
参数名称 | 类型 | 说明 |
---|---|---|
path | String | 节点路径 |
watch | boolean | 是否需要监听,为ture使用zookeeper构造方法中的监听。 |
watcher | Watcher | 自定义监听 |
cb | DataCallback | 成功获取数据后执行的回调函数 |
ctx | Object | 上下文对象 |
stat | Stat | 节点的Stat |
- 方式一: 直接获取节点数据,不设置监听
public class DataTest {
ZooKeeper zooKeeper;
@Before
public void init() throws IOException, KeeperException, InterruptedException {
String connectString = "192.168.20.132:2181";
zooKeeper = new ZooKeeper(connectString, 40000,null);
}
//获取节点数据,没有设置监听
@Test
public void getDate() throws KeeperException, InterruptedException {
byte[] data = zooKeeper.getData("/course", false, null);
System.out.println(new String(data));
}
}
运行getDate()方法, 成功获取数据
- 方式二: 获取数据并设置监听
//使用zookeeper构造方法中监听
ZooKeeper zooKeeper;
@Before
public void init() throws IOException, KeeperException, InterruptedException {
String connectString = "192.168.20.132:2181";
zooKeeper = new ZooKeeper(connectString, 40000, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println("发生改变的路径为:"+watchedEvent.getPath());
}
});
}
//watch 设置为true
@Test
public void getDate2() throws KeeperException, InterruptedException {
byte[] data = zooKeeper.getData("/course", true, null);
System.out.println(new String(data));
Thread.sleep(Long.MAX_VALUE);
}
//使用自定义监听
@Test
public void getDate3() throws KeeperException, InterruptedException {
Stat stat = new Stat();
byte[] data = zooKeeper.getData("/course", new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
//循环持续监听,否则只能监听一次
try {
zooKeeper.getData(watchedEvent.getPath(),this,null);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("自定义监听监听到"+watchedEvent.getPath()+"路径数据发生变化!!");
}
}, stat);
System.out.println(stat);
System.out.println(new String(data));
Thread.sleep(Long.MAX_VALUE);
}
执行getDate2()方法:
数据获取成功,现在更改/course节点中数据为Java,看能不能监听到:
成功监听到/course节点数据发生变化,但只能监听一次,上面定义getDate3()方法可以持续监听,使用的是自定义监听。
- 方式三:使用回调函数方式获取数据
//利用回调函数获取数据
@Test
public void getDate4() throws KeeperException, InterruptedException {
zooKeeper.getData("/course", false, new AsyncCallback.DataCallback() {
@Override
public void processResult(int rc, String path, Object ctx, byte[] bytes, Stat stat) {
System.out.println("节点Stat为:"+stat);
System.out.println("节点数据为:"+new String(bytes));
}
},"");
Thread.sleep(Long.MAX_VALUE);
}
执行getDate4():
使用Java客户端api查看/course节点的子节点:
通过org.apache.zookeeper.ZooKeeper#getChildren()即可获取子节点,其参数说明如下:
参数名称 | 类型 | 说明 |
---|---|---|
path | String | 节点路径 |
watch | boolean | 是否需要监听 |
watcher | Watcher | 自定义监听 |
cb | Children2Callback | 获取成功执行的回调函数 |
ctx | Object | 上下文对象,不常用 |
环境准备,在/course设置 java,php,python 三个子节点:
- 不包含监听获取子节点
getChildren()的返回值为包含子节点路径的集合:
@Test
public void getChildren() throws KeeperException, InterruptedException {
//false为不设置监听,为ture可以监听节点的子节点创建与删除
List<String> children = zooKeeper.getChildren("/course", false);
children.stream().forEach(System.out::println);
}
执行效果:
- 包含监听获取子节点
@Test
public void getChildern2() throws KeeperException, InterruptedException {
List<String> children = zooKeeper.getChildren("/course", new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println(watchedEvent.getPath()+"路径的子节点发生变化");
try {
zooKeeper.getChildren(watchedEvent.getPath(),this);
} catch (Exception e) {
e.printStackTrace();
}
}
});
children.stream().forEach(System.out::println);
Thread.sleep(Long.MAX_VALUE);
}
执行效果:
为/course节点添加一个子节点:
成功监听到:
使用Java客户端api创建节点:
通过org.apache.zookeeper.ZooKeeper#create()即可创建节点,其参数说明如下:
参数名称 | 类型 | 说明 |
---|---|---|
path | String | 节点路径 |
data | byte[] | 节点数据 |
acl | List | 节点访问权限 |
createMode | CreateMode | 节点类型 |
cb | StringCallback | 创建成功执行的回调函数 |
ctx | Object | 上下文对象 |
ACL包括结构为scheme: id :permission(有关ACL的介绍参照第一节课关于ACL的讲解)
客户端中由org.apache.zookeeper.data.ACL 类表示,类结构如下:
- ACL
- Id
- scheme // 对应权限模式scheme
- id // 对应模式中的id值
- perms // 对应权限位permission
关于权限位的表示方式:
每个权限位都是一个唯一数字,将其合时通过或运行生成一个全新的数字即可
@InterfaceAudience.Public
public interface Perms {
int READ = 1 << 0;
int WRITE = 1 << 1;
int CREATE = 1 << 2;
int DELETE = 1 << 3;
int ADMIN = 1 << 4;
int ALL = READ | WRITE | CREATE | DELETE | ADMIN;
}
@Test
public void createNode() throws KeeperException, InterruptedException {
List<ACL> list = new ArrayList<>();
int prem = ZooDefs.Perms.READ | ZooDefs.Perms.WRITE | ZooDefs.Perms.ADMIN;
ACL acl = new ACL(prem, new Id("world","anyone"));
ACL acl2 = new ACL(prem, new Id("ip","192.168.21.175"));
ACL acl3 = new ACL(prem, new Id("ip","127.0.0.1"));
list.add(acl);
list.add(acl2);
list.add(acl3);
zooKeeper.create("/test","测试创建节点".getBytes(),list,CreateMode.PERSISTENT);
}
执行效果:
节点创建成功,节点的权限也设置成功!!