前面一篇介绍了使用zk原生api链接zk集群进行获取子节点,获取数据的同步异步方式,本篇演示剩余其他api的代码demo.
setDataAPI 代码演示
package com.coderman.zookeeper.clusterdemo.version2;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
/**
* @description:
* @author: Fanchunshuai
* @time: 2020/2/11 10:41
* 更新数据的api
* 客户端可以通过zookeeper的api来更新一个节点的数据内容,有两个接口
* path : 指定数据节点的节点路径,
* data[]:更新节点的数据内容
* version:指定更改的数据版本
* cb:注册一个异步回调函数
* ctx:传递上下文信息的对象
*
*/
public class ZKSetDataDemo implements Watcher {
private static CountDownLatch countDownLatch = new CountDownLatch(1);
private static ZooKeeper zookeeper;
private static final int SESSION_TIMEOUT = 5000;
protected static ZooKeeper zooKeeper;
private static Stat stat = new Stat();
private static StringBuffer buffer = new StringBuffer();
static {
buffer.append("192.168.1.224:2184,");
buffer.append("192.168.1.224:2181,");
buffer.append("192.168.1.224:2182,");
buffer.append("192.168.1.224:2183,");
buffer.append("192.168.1.224:2185");
}
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
String path = "/zk-bookdemo";
zookeeper = new ZooKeeper(buffer.toString(),SESSION_TIMEOUT,new ZKSetDataDemo());
countDownLatch.await();
zookeeper.create(path,"1212".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
zooKeeper.getData(path, true, null);
Stat stat = zooKeeper.setData(path,"456".getBytes(), -1);
System.out.println(stat.getCzxid()+","+stat.getMzxid()+"," + stat.getVersion());
Thread.sleep(100000L);
}
@Override
public void process(WatchedEvent watchedEvent) {
if(Event.KeeperState.SyncConnected == watchedEvent.getState()){
if(Event.EventType.None == watchedEvent.getType() && null == watchedEvent.getPath()){
countDownLatch.countDown();
}else if(Event.EventType.NodeDataChanged == watchedEvent.getType()){
zooKeeper.getData(watchedEvent.getPath(),true,new IDataCallBack2(),null);
}
}
}
/**
* 数据类型的回调函数
*/
static class IDataCallBack2 implements AsyncCallback.DataCallback{
@Override
public void processResult(int i, String s, Object o, byte[] bytes, Stat stat) {
System.out.println("rc = "+i+",path = "+s+",data = "+new String(bytes));
System.out.println(stat.getCzxid()+","+stat.getMzxid()+","+stat.getVersion());
}
}
}
判断节点是否存在api代码演示
package com.coderman.zookeeper.clusterdemo.version2;
import org.apache.zookeeper.*;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
/**
* @description:
* @author: Fanchunshuai
* @time: 2020/2/11 10:54
* 检查节点是否存在api
* 通过本案例可以知道
* 1.无论指定节点是否存在,通过调用exists接口都可以注册watcher
* 2.exists接口中注册的watcher,能够对节点创建,节点删除,节点
* 数据更新事件进行监听。
* 3.对于指定节点的子节点的各种变化,都不会通知客户端。
*
*/
public class ZKExistAPIDemo implements Watcher {
private static CountDownLatch countDownLatch = new CountDownLatch(1);
private static ZooKeeper zooKeeper;
private static final int SESSION_TIMEOUT = 5000;
private static StringBuffer buffer = new StringBuffer();
static {
buffer.append("192.168.1.224:2184,");
buffer.append("192.168.1.224:2181,");
buffer.append("192.168.1.224:2182,");
buffer.append("192.168.1.224:2183,");
buffer.append("192.168.1.224:2185");
}
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
setData();
}
private static void setData()throws IOException, InterruptedException, KeeperException {
String path = "/zk-demo111";
zooKeeper = new ZooKeeper(buffer.toString(), SESSION_TIMEOUT, new ZKExistAPIDemo());
countDownLatch.await();
zooKeeper.exists(path, true);
zooKeeper.create(path, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zooKeeper.setData(path, "123".getBytes(), -1);
zooKeeper.create(path + "/c1", "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zooKeeper.delete(path + "/c1", -1);
zooKeeper.delete(path, -1);
Thread.sleep(100000L);
}
@Override
public void process(WatchedEvent watchedEvent) {
try {
if (Event.KeeperState.SyncConnected == watchedEvent.getState()) {
if (Event.EventType.None == watchedEvent.getType() && null == watchedEvent.getPath()) {
countDownLatch.countDown();
} else if (Event.EventType.NodeCreated == watchedEvent.getType()) {
System.out.println("Node(" + watchedEvent.getPath() + ")created");
zooKeeper.exists(watchedEvent.getPath(), true);
}else if(Event.EventType.NodeDeleted == watchedEvent.getType()){
System.out.println("Node("+watchedEvent.getPath()+")Deleted");
zooKeeper.exists(watchedEvent.getPath(),true);
}else if(Event.EventType.NodeDataChanged == watchedEvent.getType()){
System.out.println("Node("+watchedEvent.getPath()+")dataChanged");
zooKeeper.exists(watchedEvent.getPath(),true);
}
}
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
节点数据权限控制api代码
package com.coderman.zookeeper.clusterdemo.version2;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
/**
* @description:
* @author: Fanchunshuai
* @time: 2020/2/11 14:40
* zookeeper的权限控制api
* 应用场景:
* 多个业务系统公用同一套 zookeeper集群,因此需要解决不同系统之间的
* 权限问题。为了避免存储在zookeeper服务器上的数据被其他进程干扰或者人为
* 操作修改,需要对zookeeper上的数据访问进行权限控制。
* zk提供了ACL的权限控制机制。
* zk提供了多种权限控制模式,分别是world,auth,digest,ip和super.
* 开发人员如果要使用zk的权限控制功能,需要在完成zookeeper会话创建后,
* 给该会话添加上相关的权限信息。zk客户端提供了响应的api进行权限信息的设置
*
*
*
*/
public class ZKAuthAPIDemo {
private static CountDownLatch countDownLatch = new CountDownLatch(1);
private static ZooKeeper zooKeeper;
private static final int SESSION_TIMEOUT = 5000;
private static StringBuffer buffer = new StringBuffer();
static {
buffer.append("192.168.1.224:2184,");
buffer.append("192.168.1.224:2181,");
buffer.append("192.168.1.224:2182,");
buffer.append("192.168.1.224:2183,");
buffer.append("192.168.1.224:2185");
}
public static void main(String[] args) throws InterruptedException, IOException, KeeperException {
// addAuthInfoDemo();
// addAuthInfoGetDemo();
deleteAuthInfoDemo();
}
/**
* 根据权限删除节点
* @throws IOException
* @throws KeeperException
* @throws InterruptedException
*/
private static void deleteAuthInfoDemo() throws IOException, KeeperException, InterruptedException {
String path = "/zk-book-auth-test";
String path2 = "/zk-book-auth-test/child";
zooKeeper = new ZooKeeper(buffer.toString(),SESSION_TIMEOUT,null);
zooKeeper.addAuthInfo("digest","foo:true".getBytes());
zooKeeper.create(path,"init".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL,CreateMode.PERSISTENT);
zooKeeper.create(path2,"init".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL,CreateMode.EPHEMERAL);
ZooKeeper zooKeeper2 = new ZooKeeper(buffer.toString(),SESSION_TIMEOUT,null);
try {
zooKeeper2.delete(path2,-1);
}catch (Exception e){
System.out.println("删除节点失败:"+e.getMessage());
}
ZooKeeper zooKeeper3 = new ZooKeeper(buffer.toString(),SESSION_TIMEOUT,null);
zooKeeper3.addAuthInfo("digest","foo:true".getBytes());
zooKeeper3.delete(path2,-1);
System.out.println("成功删除节点:"+path2);
}
/**
* 使用包含权限信息的zookeeper会话创建数据节点
* @throws IOException
* @throws KeeperException
* @throws InterruptedException
*/
private static void addAuthInfoDemo() throws IOException, KeeperException, InterruptedException {
String path = "/zk-book-auth-info";
zooKeeper = new ZooKeeper(buffer.toString(),SESSION_TIMEOUT,null);
zooKeeper.addAuthInfo("digest","foo:true".getBytes());
zooKeeper.create(path,"init".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
Thread.sleep(10000L);
}
/**
* 事务无权限信息的zookeeper会话访问包含权限信息的数据节点
* @throws IOException
* @throws KeeperException
* @throws InterruptedException
*/
private static void addAuthInfoGetDemo() throws IOException, KeeperException, InterruptedException {
String path = "/zk-book-auth-info";
zooKeeper = new ZooKeeper(buffer.toString(),SESSION_TIMEOUT,null);
zooKeeper.addAuthInfo("digest","foo:true".getBytes());
zooKeeper.create(path,"init".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
ZooKeeper zooKeeper2 = new ZooKeeper(buffer.toString(),SESSION_TIMEOUT,null);
zooKeeper2.addAuthInfo("digest","foo:false".getBytes());
zooKeeper2.getData(path,false,null);
Thread.sleep(10000L);
}
}