005_Java操作ZooKeeper
1. ZooKeeper的JavaClient是我們更輕松的去對ZooKeeper進行各種操作。我們僅需要引入zookeeper-3.7.0.jar和zookeeper-jute-3.7.0.jar兩個jar包即可。
2. 創建會話
2.1. 客戶端可以創建一個ZooKeeper實例來連接ZooKeeper服務器。
2.2. ZooKeeper構造函數的connectString參數, 連接服務器列表, 使用,分割多個服務器地址。
2.3. ZooKeeper構造函數的sessionTimeout參數, 心跳檢測時間周期, 以毫秒為單位。
2.4. ZooKeeper構造函數的watcher參數, 事件處理通知器。
2.5. ZooKeeper客戶端和服務器會話的創建是一個異步的過程, 也就是說在程序中, ZooKeeper實例創建完成后立即返回, 但是大多數情況下我們并沒有真正構建好一個可用會話, 在會話的生命周期處于CONNECTING時才算真正建立完畢。
3. 創建節點?
3.1. ZooKeeper提供了兩套創建節點的方法, 同步和異步創建節點方式。
3.2. 創建節點path參數, 節點路徑, 不允許遞歸創建節點。
3.3. 創建節點data參數, 節點內容, 字節數組類型。
3.4. 創建節點acl參數, 節點權限, 最簡單的值Ids.OPEN_ACL_UNSAFE開放權限。
3.5. 創建節點createMode參數, 創建節點類型。CreateMode.PERSISTENT持久節點; CreateMode.PERSISTENT_SEQUENTIAL持久順序節點; CreateMode.EPHEMERAL臨時節點; CreateMode.EPHEMERAL_SEQUENTIAL臨時順序節點。
3.6. 創建節點Create2Callback參數, 注冊一個異步回調函數。rc: 服務器相應碼, 0表示創建成功, -4表示端口未連接, -110表示指定節點存在, -112表示會話過期。path: 接口調用時傳入API的數據節點的路徑參數。xtx: 為接口傳入API的上下文參數值。name: 實際在服務器端創建節點的名稱。stat: 節點屬性信息。
3.7. 創建節點ctx參數, 為接口調用傳入上下文參數。
4. 創建節點例子
4.1. 新建一個名為zookeeper的Java項目, 同時拷入相關jar包
4.2. 創建Create.java
package com.zk.rm;import java.io.IOException; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.AsyncCallback.Create2Callback; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooDefs.Ids; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.data.Stat;public class Create {private static final String connectString = "192.168.25.133:2181,192.168.25.135:2181,192.168.25.138:2181";private static final CountDownLatch cdl = new CountDownLatch(1);public static void main(String[] args) {try {// 創建連接ZooKeeper zk = new ZooKeeper(connectString, 5000, new Watcher() {@Overridepublic void process(WatchedEvent event) {if(KeeperState.SyncConnected == event.getState()) {// 剛剛連接成功, 沒有事件if(EventType.None == event.getType()) {// 如果建立連接成功, 發送信號量, 讓后續阻塞程序能夠繼續向下執行cdl.countDown();System.out.println("建立連接成功了。");} }}});// 進行阻塞cdl.await();// 創建父節點String ret = zk.create("/myRoot", "創建了一個我的根節點。".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);System.out.println(System.currentTimeMillis() + " " + ret);// 異步創建子節點zk.create("/myRoot/child1", "根節點上創建了一個child1的子節點".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL, new Create2Callback() {@Overridepublic void processResult(int rc, String path, Object ctx, String name, Stat stat) {System.out.println("rc = " + rc + ", path = " + path + ", ctx = " + ctx + ", name = " + name);}}, "/myRoot/child1下文參數");zk.create("/myRoot/child2", "根節點上創建了一個child2的子節點".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL, new Create2Callback() {@Overridepublic void processResult(int rc, String path, Object ctx, String name, Stat stat) {System.out.println("rc = " + rc + ", path = " + path + ", ctx = " + ctx + ", name = " + name);}}, "/myRoot/child2下文參數");// 關閉連接zk.close();} catch (InterruptedException | IOException | KeeperException e) {e.printStackTrace();}} }4.3. 運行結果
5. 刪除節點
5.1. delete刪除節點也有同步刪除和異步刪除兩套API。
5.2. 刪除節點path參數, 節點名稱。
5.3. 刪除節點version參數, 版本號, -1跳過版本檢查。
5.4. 刪除節點cb參數, 一個異步回調函數。
5.5. 刪除節點ctx參數, 用于傳遞上下文信息的對象。
5.6. 在ZooKeeper中, 只允許刪除葉子節點信息, 也就是說如果節點下還有子孫節點, 必須刪除所有子孫節點才能刪除該節點。
6. 檢查節點是否存在
6.1. exists檢查節點是否存在方法也有同步檢查和異步檢查兩套API。
6.2. 檢查節點是否存在path參數, 節點名稱。
6.3. 檢查節點是否存在watch參數, 注冊一個監聽對象。
6.4. 檢查節點是否存在cb參數, 一個異步回調函數。
6.5. 檢查節點是否存在ctx參數, 用于傳遞上下文信息的對象。
7. 刪除和檢查節點是否存在例子
7.1. 創建ExistsDelete.java
package com.zk.rm;import java.io.IOException; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.AsyncCallback.VoidCallback; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooKeeper;public class ExistsDelete {private static final String connectString = "192.168.25.133:2181,192.168.25.135:2181,192.168.25.138:2181";private static final CountDownLatch cdl = new CountDownLatch(1);public static void main(String[] args) {try {ZooKeeper zk = new ZooKeeper(connectString, 5000, new Watcher() {@Overridepublic void process(WatchedEvent event) {if(KeeperState.SyncConnected == event.getState()) {if(EventType.None == event.getType()) {// 如果建立連接成功, 發送信號量, 讓后續阻塞程序能夠繼續向下執行cdl.countDown();System.out.println("建立連接成功了。");}}}});// 進行阻塞cdl.await();if(zk.exists("/myRoot", null) != null) {// 同步刪除方法// zk.delete("/myRoot", -1);// 異步刪除方法zk.delete("/myRoot", -1, new VoidCallback() {@Overridepublic void processResult(int rc, String path, Object ctx) {System.out.println("rc = " + rc + ", path = " + path + ", ctx = " + ctx);}}, "delete /myRoot上下文參數");}zk.close();} catch (InterruptedException | IOException | KeeperException e) {e.printStackTrace();}} }7.2. 運行結果
8. 獲取子節點例子
8.1. 創建GetChildren.java
package com.zk.rm;import java.io.IOException; import java.util.List; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooKeeper;public class GetChildren {private static final String connectString = "192.168.25.133:2181,192.168.25.135:2181,192.168.25.138:2181";private static final CountDownLatch cdl = new CountDownLatch(1);public static void main(String[] args) {try {ZooKeeper zk = new ZooKeeper(connectString, 5000, new Watcher() {@Overridepublic void process(WatchedEvent event) {if(KeeperState.SyncConnected == event.getState()) {// 剛剛連接成功, 沒有事件if(EventType.None == event.getType()) {// 如果建立連接成功, 發送信號量, 讓后續阻塞程序能夠繼續向下執行cdl.countDown();System.out.println("建立連接成功了。");}}}});// 進行阻塞cdl.await();// 獲取子節點List<String> children = zk.getChildren("/", false);for (String child : children) {System.out.println(child);}zk.close();} catch (InterruptedException | IOException | KeeperException e) {e.printStackTrace();}} }8.2. 運行結果
9. 設置和獲取節點例子
9.1. 創建GetSetData.java
package com.zk.rm;import java.io.IOException; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.data.Stat;public class GetSetData {private static final String connectString = "192.168.25.133:2181,192.168.25.135:2181,192.168.25.138:2181";private static final CountDownLatch cdl = new CountDownLatch(1);public static void main(String[] args) {try {ZooKeeper zk = new ZooKeeper(connectString, 5000, new Watcher() {@Overridepublic void process(WatchedEvent event) {if(KeeperState.SyncConnected == event.getState()) {if(EventType.None == event.getType()) {// 如果建立連接成功, 發送信號量, 讓后續阻塞程序能夠繼續向下執行cdl.countDown();System.out.println("建立連接成功了。");}}}});// 進行阻塞cdl.await();// 獲取節點byte[] data = zk.getData("/myRoot", false, null);System.out.println("根節點數據: " + new String(data));Stat stat = zk.setData("/myRoot", "modify data".getBytes(), -1);System.out.println("czxid: " + stat.getCzxid() + ", ctime: " + stat.getCtime() + ", cversion: " + stat.getCversion());System.out.println("mzxid: " + stat.getMzxid() + ", mtime: " + stat.getMtime() + ", pzxid: " + stat.getPzxid());System.out.println("version: " + stat.getVersion() + ", dataLength: " + stat.getDataLength() + ", aversion: " + stat.getAversion());System.out.println("numChildren: "+ stat.getNumChildren() + ", ephemeralOwner: " + stat.getEphemeralOwner());zk.close();} catch (InterruptedException | IOException | KeeperException e) {e.printStackTrace();}} }9.2. 運行結果
10. watch事件
10.1. ZooKeeper的watch事件監聽節點的變化, 當節點發生變化時, 通知注冊了監聽的客戶端。
10.2. 事件類型: EventType.NodeCreated創建節點; EventType.NodeDataChanged節點數據發生變化; EventType.NodeChildrenChanged子節點發生變化; EventType.NodeDeleted刪除節點。
10.3. 狀態類型: KeeperState.SyncConnected建立連接成功; KeeperState.Disconnected未連接; KeeperState.AuthFailed認證失敗; KeeperState.Expired連接過期。
11. watch事件例子
11.1.?創建Watch.java
package com.zk.rm;import java.io.IOException; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.AddWatchMode; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooDefs.Ids; import org.apache.zookeeper.ZooKeeper;public class Watch {private static final String connectString = "192.168.25.133:2181,192.168.25.135:2181,192.168.25.138:2181";private static final CountDownLatch cdl = new CountDownLatch(1);private static ZooKeeper zk;public static void main(String[] args) {try {zk = new ZooKeeper(connectString, 5000, new Watcher() {@Overridepublic void process(WatchedEvent event) {if(KeeperState.SyncConnected == event.getState()) {try {if(EventType.None == event.getType()) {// 如果建立連接成功, 發送信號量, 讓后續阻塞程序能夠繼續向下執行cdl.countDown();System.out.println("建立連接成功了。");} else if (EventType.NodeDataChanged == event.getType()) {System.out.println("data = " + new String(zk.getData("/myRoot", false, null)));} else if (EventType.NodeChildrenChanged == event.getType()) {System.out.println("allChildrenNumber = "+ zk.getAllChildrenNumber("/myRoot"));} else if (EventType.NodeCreated == event.getType()) {System.out.println("創建節點");} else if (EventType.NodeDeleted == event.getType()) {System.out.println("刪除節點");}} catch (KeeperException | InterruptedException e) {e.printStackTrace();}}}});// 進行阻塞cdl.await();// 添加節點監聽zk.addWatch("/myRoot", AddWatchMode.PERSISTENT_RECURSIVE);String childRet2 = zk.create("/myRoot/child2", "根節點上創建了一個child2的子節點".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);System.out.println(childRet2);zk.setData("/myRoot", "修改/myRoot節點數據".getBytes(), -1);zk.delete("/myRoot/child2", -1);Thread.sleep(60000);zk.close();} catch (KeeperException | IOException | InterruptedException e) {e.printStackTrace();}} }11.2. 運行結果
12. ACL例子
12.1. 創建AccessControlList.java
package com.zk.rm;import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooDefs.Perms; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.data.ACL; import org.apache.zookeeper.data.Id; import org.apache.zookeeper.server.auth.DigestAuthenticationProvider;public class AccessControlList {private static final String connectString = "192.168.25.133:2181,192.168.25.135:2181,192.168.25.138:2181";private static final CountDownLatch cdl = new CountDownLatch(1);public static void main(String[] args) {try {ZooKeeper zk = new ZooKeeper(connectString, 5000, new Watcher() {@Overridepublic void process(WatchedEvent event) {if(KeeperState.SyncConnected == event.getState()) {if(EventType.None == event.getType()) {// 如果建立連接成功, 發送信號量, 讓后續阻塞程序能夠繼續向下執行cdl.countDown();System.out.println("建立連接成功了。");}}}});// 進行阻塞cdl.await();List<ACL> acls = new ArrayList<ACL>();Id id1 = new Id("digest", DigestAuthenticationProvider.generateDigest("zs:123456"));ACL acl = new ACL(Perms.ALL, id1);acls.add(acl);String rt = zk.create("/myRoot", "my root data".getBytes(), acls, CreateMode.PERSISTENT);System.out.println(rt);zk.addAuthInfo("digest", "zs:123456".getBytes());System.out.println(new String(zk.getData("/myRoot", null, null)));zk.close();} catch (KeeperException | IOException | InterruptedException | NoSuchAlgorithmException e) {e.printStackTrace();}} }12.2. 運行結果
總結
以上是生活随笔為你收集整理的005_Java操作ZooKeeper的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 004_ZooKeeper客户端基础命令
- 下一篇: 006_Curator框架一