前面一篇介紹了使用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);
}
}