目錄
一、zookeeper java api
zookeeper 可以通過java api連接操作,進行ZNode的創建刪除,數據的獲取設置,子節點的獲取已經狀態的觀察,權限的設置。並且zookeeper客戶端提供了異步操作,並有監聽機制,更爲方便的提供對zookeeper數據的監聽和維護。
上一篇文章提到的可以通過控制命令行操作zookeeper數據節點,同樣,zookeeper官方爲我們提供了相應的java api 操作。
https://blog.csdn.net/qq_33513250/article/details/101618808
客戶端連接後我們可以做如下操作:
創建znode、獲取數據、設置數據、獲取子節點、權限設置、節點存在判斷、刪除節點
二、pom 文件
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
</dependency>
三、同步操作
1.創建節點
package com.szwn.zk;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import java.util.concurrent.CountDownLatch;
public class CreateNode implements Watcher{
private static CountDownLatch connectedSemaphore = new CountDownLatch(1);
public static void main(String[] args) throws Exception {
// 1.連接zookeeper 客戶端,參數分別爲服務器連接地址,集羣用逗號隔開,sessionTimeout,事件監聽器
ZooKeeper zookeeper = new ZooKeeper("127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183", 5000, new CreateNode());
System.out.println(zookeeper.getState());
// 2.等待連接完成
connectedSemaphore.await();
// 3.創建節點,節點類型爲persistent
String path1 = zookeeper.create("/create-test-ephemeral-", "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("Success create znode: " + path1);
// 4.創建節點,節點類型爲ephemeral-sequential
String path2 = zookeeper.create("/create-test-ephemeral-", "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println("Success create znode: " + path2);
}
/**
* WatchedEvent 事件監聽
* 服務器回調監聽器連接成功
* @param event
*/
public void process(WatchedEvent event) {
if (Event.KeeperState.SyncConnected == event.getState()) {
connectedSemaphore.countDown();
}
}
}
2.獲取數據
package com.szwn.zk;
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
public class GetData implements Watcher {
private static CountDownLatch connectedSemaphore = new CountDownLatch(1);
private static ZooKeeper zk = null;
private static Stat stat = new Stat();
public static void main(String[] args) throws Exception {
String path = "/zk-book";
// 1.連接zookeeper 客戶端,參數分別爲服務器連接地址,集羣用逗號隔開,sessionTimeout,事件監聽器
zk = new ZooKeeper("127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183", 5000, new GetData());
// 2.等待連接完成
connectedSemaphore.await();
// 3.創建節點,節點類型爲ephemeral,數據爲123
zk.create(path, "123".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println("success create znode: " + path);
// 4.獲取數據,且爲監聽模式,並把數據狀態存入 stat中
System.out.println("the data of znode " + path + " is : " + new String(zk.getData(path, true, stat)));
System.out.println("czxID: " + stat.getCzxid() + ", mzxID: " + stat.getMzxid() + ", version: " + stat.getVersion());
// 5.根據版本號-1 修改數據1234
zk.setData(path, "1234".getBytes(), -1);
Thread.sleep(Integer.MAX_VALUE);
}
public void process(WatchedEvent event) {
if (Event.KeeperState.SyncConnected == event.getState()) {
// 連接監聽,連接狀態,空事件則爲連接session成功
if (Event.EventType.None == event.getType() && null == event.getPath()) {
connectedSemaphore.countDown();
} else if (event.getType() == Event.EventType.NodeDataChanged) {
// node data changed 監聽
try {
System.out.println("the data of znode " + event.getPath() + " is : " + new String(zk.getData(event.getPath(), true, stat)));
System.out.println("czxID: " + stat.getCzxid() + ", mzxID: " + stat.getMzxid() + ", version: " + stat.getVersion());
} catch (Exception e) {
}
}
}
}
}
3.設置數據
package com.szwn.zk;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import java.util.concurrent.CountDownLatch;
public class SetData implements Watcher {
private static CountDownLatch connectedSemaphore = new CountDownLatch(1);
private static ZooKeeper zk;
public static void main(String[] args) throws Exception {
String path = "/zk-book-set";
// 1.連接zookeeper 客戶端,參數分別爲服務器連接地址,集羣用逗號隔開,sessionTimeout,事件監聽器
zk = new ZooKeeper("127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183", 5000, new SetData());
// 2.等待連接完成
connectedSemaphore.await();
// 3.創建節點,節點類型爲ephemeral,數據爲123
zk.create(path, "123".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println("success create znode: " + path);
// 4.獲取數據,且爲監聽模式
zk.getData(path, true, null);
// 5.根據版本號-1 修改數據456
Stat stat = zk.setData(path, "456".getBytes(), -1);
System.out.println("czxID: " + stat.getCzxid() + ", mzxID: " + stat.getMzxid() + ", version: " + stat.getVersion());
// 6.根據版本號,上一次修改後的版本號,設置數據456
Stat stat2 = zk.setData(path, "456".getBytes(), stat.getVersion());
System.out.println("czxID: " + stat2.getCzxid() + ", mzxID: " + stat2.getMzxid() + ", version: " + stat2.getVersion());
try {
// 7.錯誤版本號設置數據,報錯
zk.setData(path, "456".getBytes(), stat.getVersion());
} catch (KeeperException e) {
System.out.println("Error: " + e.code() + "," + e.getMessage());
}
Thread.sleep(Integer.MAX_VALUE);
}
public void process(WatchedEvent event) {
if (Event.KeeperState.SyncConnected == event.getState()) {
// 連接監聽,連接狀態,空事件則爲連接session成功
if (Event.EventType.None == event.getType() && null == event.getPath()) {
connectedSemaphore.countDown();
}
}
}
}
4.獲取子節點
package com.szwn.zk;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import java.util.List;
import java.util.concurrent.CountDownLatch;
public class GetChildren implements Watcher{
private static CountDownLatch connectedSemaphore = new CountDownLatch(1);
private static ZooKeeper zk = null;
public static void main(String[] args) throws Exception {
String path = "/zk-book-1";
// 1.連接zookeeper 客戶端,參數分別爲服務器連接地址,集羣用逗號隔開,sessionTimeout,事件監聽器
zk = new ZooKeeper("127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183", 5000, new GetChildren());
// 2.等待連接完成
connectedSemaphore.await();
// 3.創建節點,節點類型爲persistent,數據爲空
zk.create(path, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("success create znode: " + path);
// 4.創建子節點,路徑爲path/c1,節點類型爲ephemeral,數據爲空
zk.create(path + "/c1", "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println("success create znode: " + path + "/c1");
// 5.獲取path的子節點,並監聽變化
List<String> childrenList = zk.getChildren(path, true);
System.out.println(childrenList);
// 4.創建子節點,路徑爲path/c2,節點類型爲ephemeral,數據爲空
zk.create(path + "/c2", "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println("success create znode: " + path + "/c2");
Thread.sleep(1000);
// 4.創建子節點,路徑爲path/c3,節點類型爲ephemeral,數據爲空
zk.create(path + "/c3", "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println("success create znode: " + path + "/c3");
Thread.sleep(Integer.MAX_VALUE);
}
public void process(WatchedEvent event) {
if (Event.KeeperState.SyncConnected == event.getState()) {
// 連接監聽,連接狀態,空事件則爲連接session成功
if (Event.EventType.None == event.getType() && null == event.getPath()) {
connectedSemaphore.countDown();
// 監聽node children changed event
} else if (event.getType() == Event.EventType.NodeChildrenChanged) {
try {
System.out.println("ReGet Child:" + zk.getChildren(event.getPath(), true));
} catch (Exception e) {
}
}
}
}
}
5.節點權限控制
package com.szwn.zk;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
public class Auth {
final static String PATH = "/zk-book-auth_test";
public static void main(String[] args) throws Exception {
// 1.連接zookeeper 客戶端,參數分別爲服務器連接地址,集羣用逗號隔開,sessionTimeout,事件監聽器
ZooKeeper zookeeper1 = new ZooKeeper("127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183", 5000, null);
// 2.連接添加權限信息,scheme和data
zookeeper1.addAuthInfo("digest", "foo:true".getBytes());
// 3.創建節點,數據爲init
// 權限爲 CREATOR_ALL_ACL(This ACL gives the creators authentication id's all permissions.)
zookeeper1.create(PATH, "init".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL, CreateMode.EPHEMERAL);
System.out.println("success create znode: " + PATH);
// 4.創建第二個session
ZooKeeper zookeeper2 = new ZooKeeper("127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183", 5000, null);
// 5.獲取第一個數據
byte[] data = zookeeper2.getData(PATH, false, null);
System.out.println(new String(data));
}
}
第二個客戶端沒有path的權限,運行結果爲
6.節點存在
package com.szwn.zk;
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
public class Exist implements Watcher {
private static CountDownLatch connectedSemaphore = new CountDownLatch(1);
private static ZooKeeper zk;
public static void main(String[] args) throws Exception {
String path = "/zk-book";
// 1.連接zookeeper 客戶端,參數分別爲服務器連接地址,集羣用逗號隔開,sessionTimeout,事件監聽器
zk = new ZooKeeper("127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183", 5000, new Exist());
// 2.等待連接完成
connectedSemaphore.await();
// 3.判斷path節點是否存在,並啓動監聽
Stat exists = zk.exists(path, true);
System.out.println(exists);
// 4.創建path節點並設置數據爲123
zk.create(path, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zk.setData(path, "123".getBytes(), -1);
// 5.創建path/c1子節點
zk.create(path + "/c1", "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("success create znode: " + path + "/c1");
// 6.刪除path/c1子節點
zk.delete(path + "/c1", -1);
zk.delete(path, -1);
Thread.sleep(Integer.MAX_VALUE);
}
public void process(WatchedEvent event) {
try {
if (Event.KeeperState.SyncConnected == event.getState()) {
// 連接監聽,連接狀態,空事件則爲連接session成功
if (Event.EventType.None == event.getType() && null == event.getPath()) {
connectedSemaphore.countDown();
// node created 監聽,因爲對節點的操作監聽爲下一次有效,所以設置監聽爲true,繼續監聽節點下次狀態變化
} else if (Event.EventType.NodeCreated == event.getType()) {
System.out.println("success create znode: " + event.getPath());
zk.exists(event.getPath(), true);
// node deleted 監聽
} else if (Event.EventType.NodeDeleted == event.getType()) {
System.out.println("success delete znode: " + event.getPath());
zk.exists(event.getPath(), true);
// node data changed 監聽
} else if (Event.EventType.NodeDataChanged == event.getType()) {
System.out.println("data changed of znode: " + event.getPath());
zk.exists(event.getPath(), true);
}
}
} catch (Exception e) {
}
}
}
7.刪除節點
package com.szwn.zk;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import java.util.concurrent.CountDownLatch;
public class DeleteNode implements Watcher {
private static CountDownLatch connectedSemaphore = new CountDownLatch(1);
private static ZooKeeper zk;
public static void main(String[] args) throws Exception {
String path = "/zk-book";
// 1.連接zookeeper 客戶端,參數分別爲服務器連接地址,集羣用逗號隔開,sessionTimeout,事件監聽器
zk = new ZooKeeper("127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183", 5000,
new DeleteNode());
// 2.等待連接完成
connectedSemaphore.await();
// 3.創建節點,節點類型爲persistent
zk.create(path, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("success create znode: " + path);
// 4.創建子節點,節點類型爲persistent
zk.create(path + "/c1", "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("success create znode: " + path + "/c1");
try {
// 5.刪除父節點,因爲有子節點,報錯
zk.delete(path, -1);
} catch (Exception e) {
System.out.println("fail to delete znode: " + path);
}
// 6.刪除子節點
zk.delete(path + "/c1", -1);
System.out.println("success delete znode: " + path + "/c1");
// 7.刪除父節點
zk.delete(path, -1);
System.out.println("success delete znode: " + path);
Thread.sleep(Integer.MAX_VALUE);
}
public void process(WatchedEvent event) {
if (Event.KeeperState.SyncConnected == event.getState()) {
if (Event.EventType.None == event.getType() && null == event.getPath()) {
connectedSemaphore.countDown();
}
}
}
}
運行結果