ZooKeeper(3.4.5) - 原生 API 的简单示例
一、创建会话
1. 创建一个基本的ZooKeeper会话实例
package com.huey.dream.demo; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.Watcher.Event.KeeperState; /** * 创建一个基本的ZooKeeper会话实例 * @author huey * @version 1.0 * @created 2015-3-1 */ public class ZKDemo { public static void main(String[] args) throws Exception { final CountDownLatch connectedSignal = new CountDownLatch(1); /** * ZooKeeper客户端和服务器会话的建立是一个异步的过程 * 构造函数在处理完客户端的初始化工作后立即返回,在大多数情况下,并没有真正地建立好会话 * 当会话真正创建完毕后,Zookeeper服务器会向客户端发送一个事件通知 */ ZooKeeper zk = new ZooKeeper("192.168.1.109:2181", 5000, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == KeeperState.SyncConnected) { connectedSignal.countDown(); } } }); System.out.println("State1: " + zk.getState()); // CONNECTING connectedSignal.await(); System.out.println("State2: " + zk.getState()); // CONNECTED zk.close(); System.out.println("State3: " + zk.getState()); // CLOSED } }
2. 创建一个复用sessionId和sessionPasswd的Zookeeper对象示例
package com.huey.dream.demo; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.Watcher.Event.KeeperState; /** * 创建一个复用sessionId和sessionPasswd的ZooKeeper对象示例 * @author huey * @version 1.0 * @created 2015-3-1 */ public class ZKDemo { public static void main(String[] args) throws Exception { final CountDownLatch connectedSignal = new CountDownLatch(1); ZooKeeper zk = new ZooKeeper("192.168.1.109:2181", 5000, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == KeeperState.SyncConnected) { connectedSignal.countDown(); } } }); connectedSignal.await(); long sessionId = zk.getSessionId(); byte[] passwd = zk.getSessionPasswd(); zk.close(); final CountDownLatch anotherConnectedSignal = new CountDownLatch(1); ZooKeeper newZk = new ZooKeeper( "192.168.1.109:2181", 5000, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == KeeperState.SyncConnected) { anotherConnectedSignal.countDown(); } } }, sessionId, passwd); anotherConnectedSignal.await(); newZk.close(); } }
二、创建节点
1. 使用同步API创建一个ZNode节点
package com.huey.dream.demo; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooDefs.Ids; /** * 使用同步API创建一个ZNode节点 * @author huey * @version 1.0 * @created 2015-3-1 */ public class ZKDemo { public static void main(String[] args) throws Exception { final CountDownLatch connectedSignal = new CountDownLatch(1); ZooKeeper zk = new ZooKeeper("192.168.1.109:2181", 5000, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == KeeperState.SyncConnected) { connectedSignal.countDown(); } } }); connectedSignal.await(); String path = zk.create( "/zk-huey", "hello".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT ); System.out.println(path + " is created."); zk.close(); } }
2. 使用异步API创建一个ZNode节点
package com.huey.dream.demo; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.AsyncCallback; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooDefs.Ids; /** * 使用异步API创建一个ZNode节点 * @author huey * @version 1.0 * @created 2015-3-1 */ public class ZKDemo { public static void main(String[] args) throws Exception { final CountDownLatch connectedSignal = new CountDownLatch(1); ZooKeeper zk = new ZooKeeper("192.168.1.109:2181", 5000, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == KeeperState.SyncConnected) { connectedSignal.countDown(); } } }); connectedSignal.await(); zk.create( "/zk-huey", "hello".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL, new AsyncCallback.StringCallback() { @Override public void processResult(int rc, String path, Object ctx, String name) { // 服务器响应吗 System.out.println("ResultCode: " + rc); // 接口调用时传入API的数据节点的路径参数值 System.out.println("Znode: " + path); // 接口调用时传入API的ctx参数值 System.out.println("Context: " + (String)ctx); // 实际在服务端创建的节点名 System.out.println("Real Path: " + name); } }, "The Context" ); zk.close(); } }
三、删除节点
1. 使用同API删除一个ZNode节点
package com.huey.dream.demo; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.Watcher.Event.KeeperState; /** * 使用同步API删除一个ZNode节点 * @author huey * @version 1.0 * @created 2015-3-1 */ public class ZKDemo { public static void main(String[] args) throws Exception { final CountDownLatch connectedSignal = new CountDownLatch(1); ZooKeeper zk = new ZooKeeper("192.168.1.109:2181", 5000, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == KeeperState.SyncConnected) { connectedSignal.countDown(); } } }); connectedSignal.await(); zk.delete("/zk-huey", -1); zk.close(); } }
2. 使用异步API删除一个ZNode节点
package com.huey.dream.demo; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.AsyncCallback; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.Watcher.Event.KeeperState; /** * 使用异步API删除一个ZNode节点 * @author huey * @version 1.0 * @created 2015-3-1 */ public class ZKDemo { public static void main(String[] args) throws Exception { final CountDownLatch connectedSignal = new CountDownLatch(1); ZooKeeper zk = new ZooKeeper("192.168.1.109:2181", 5000, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == KeeperState.SyncConnected) { connectedSignal.countDown(); } } }); connectedSignal.await(); zk.delete( "/zk-huey", -1, new AsyncCallback.VoidCallback() { @Override public void processResult(int rc, String path, Object ctx) { System.out.println("ResultCode: " + rc); System.out.println("Znode: " + path); System.out.println("Context: " + (String)ctx); } }, "The Context" ); zk.close(); } }
四、获取子节点列表
1. 使用同步API获取子节点列表
package com.huey.dream.demo; 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.ZooKeeper; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooDefs.Ids; import org.apache.zookeeper.data.Stat; /** * 使用同步API获取子节点列表 * @author huey * @version 1.0 * @created 2015-3-1 */ public class ZKDemo { public static void main(String[] args) throws Exception { final CountDownLatch connectedSignal = new CountDownLatch(1); final ZooKeeper zk = new ZooKeeper("192.168.1.109:2182", 5000, null); zk.register(new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == KeeperState.SyncConnected) { if (event.getType() == EventType.None && event.getPath() == null) { connectedSignal.countDown(); } else if (event.getType() == EventType.NodeChildrenChanged) { try { System.out.println("NodeChildrenChanged."); List<String> children = zk.getChildren(event.getPath(), true); System.out.println("Children: " + children); } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }); connectedSignal.await(); zk.create("/zk-huey", "root".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); zk.create("/zk-huey/node1", "node1".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); zk.create("/zk-huey/node2", "node2".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); Stat stat = new Stat(); List<String> children = zk.getChildren("/zk-huey", true, // 注册默认的Watcher,当子节点类别发送变更的话,向客户端发送通知 stat // 用于描述节点状态信息 ); System.out.println("Stat: " + stat); System.out.println("Children: " + children); zk.create("/zk-huey/node3", "node3".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); Thread.sleep(10 * 1000); zk.close(); } }
结果输出:
Stat: 4294967436,4294967436,1425201236879,1425201236879,0,2,0,0,4,2,4294967438 Children: [node2, node1] NodeChildrenChanged. State: CONNECTED Children: [node2, node3, node1]
2. 使用异步API获取子节点列表
package com.huey.dream.demo; import java.util.List; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.AsyncCallback; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooDefs.Ids; import org.apache.zookeeper.data.Stat; /** * 使用异步API获取子节点列表 * @author huey * @version 1.0 * @created 2015-3-1 */ public class ZKDemo { public static void main(String[] args) throws Exception { final CountDownLatch connectedSignal = new CountDownLatch(1); final ZooKeeper zk = new ZooKeeper("192.168.1.109:2182", 5000, null); zk.register(new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == KeeperState.SyncConnected) { if (event.getType() == EventType.None && event.getPath() == null) { connectedSignal.countDown(); } else if (event.getType() == EventType.NodeChildrenChanged) { try { System.out.println("NodeChildrenChanged."); List<String> children = zk.getChildren(event.getPath(), true); System.out.println("Children: " + children); } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }); connectedSignal.await(); zk.create("/zk-huey", "root".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); zk.create("/zk-huey/node1", "node1".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); zk.create("/zk-huey/node2", "node2".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); zk.getChildren("/zk-huey", true, new AsyncCallback.Children2Callback() { @Override public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) { System.out.println("ResultCode: " + rc); System.out.println("ZNode: " + path); System.out.println("Context: " + ctx); System.out.println("Children: " + children); System.out.println("Stat: " + stat); } }, "The Context" ); zk.create("/zk-huey/node3", "node3".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); Thread.sleep(10 * 1000); zk.close(); } }
五、获取节点数据内容
1. 使用同步API获取节点数据内容
package com.huey.dream.demo; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooDefs.Ids; /** * 使用同步API获取节点数据内容 * @author huey * @version 1.0 * @created 2015-3-1 */ public class ZKDemo { public static void main(String[] args) throws Exception { final CountDownLatch connectedSignal = new CountDownLatch(1); final ZooKeeper zk = new ZooKeeper("192.168.1.109:2182", 5000, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == KeeperState.SyncConnected) { if (event.getType() == EventType.None && event.getPath() == null) { connectedSignal.countDown(); } } } }); connectedSignal.await(); zk.create("/zk-huey", "hello".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); byte[] nodeData = zk.getData("/zk-huey", false, null); System.out.println("NodeData: " + new String(nodeData)); zk.close(); } }
2. 使用异步API获取节点数据内容
package com.huey.dream.demo; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.AsyncCallback; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooDefs.Ids; import org.apache.zookeeper.data.Stat; /** * 使用异步API获取节点数据内容 * @author huey * @version 1.0 * @created 2015-3-1 */ public class ZKDemo { public static void main(String[] args) throws Exception { final CountDownLatch connectedSignal = new CountDownLatch(1); final ZooKeeper zk = new ZooKeeper("192.168.1.109:2182", 5000, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == KeeperState.SyncConnected) { if (event.getType() == EventType.None && event.getPath() == null) { connectedSignal.countDown(); } } } }); connectedSignal.await(); zk.create("/zk-huey", "hello".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); zk.getData( "/zk-huey", false, new AsyncCallback.DataCallback() { @Override public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) { System.out.println("ResultCode: " + rc); System.out.println("ZNode: " + path); System.out.println("Context: " + ctx); System.out.println("NodeData: " + new String(data)); System.out.println("Stat: " + stat); } }, "The Context" ); zk.close(); } }
六、更新数据
1. 使用同步API更新节点数据内容
package com.huey.dream.demo; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooDefs.Ids; /** * 使用同步API更新节点数据内容 * @author huey * @version 1.0 * @created 2015-3-1 */ public class ZKDemo { public static void main(String[] args) throws Exception { final CountDownLatch connectedSignal = new CountDownLatch(1); final ZooKeeper zk = new ZooKeeper("192.168.1.109:2182", 5000, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == KeeperState.SyncConnected) { if (event.getType() == EventType.None && event.getPath() == null) { connectedSignal.countDown(); } } } }); connectedSignal.await(); zk.create("/zk-huey", "hello".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); byte[] nodeData = zk.getData("/zk-huey", false, null); System.out.println("NodeData: " + nodeData); zk.setData("/zk-huey", "world".getBytes(), -1); nodeData = zk.getData("/zk-huey", false, null); System.out.println("NodeData: " + nodeData); zk.close(); } }
2. 使用异步API更新节点数据内容
package com.huey.dream.demo; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.AsyncCallback; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooDefs.Ids; import org.apache.zookeeper.data.Stat; /** * 使用异步API更新节点数据内容 * @author huey * @version 1.0 * @created 2015-3-1 */ public class ZKDemo { public static void main(String[] args) throws Exception { final CountDownLatch connectedSignal = new CountDownLatch(1); final ZooKeeper zk = new ZooKeeper("192.168.1.109:2182", 5000, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == KeeperState.SyncConnected) { if (event.getType() == EventType.None && event.getPath() == null) { connectedSignal.countDown(); } } } }); connectedSignal.await(); zk.create("/zk-huey", "hello".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); byte[] nodeData = zk.getData("/zk-huey", false, null); System.out.println("NodeData: " + nodeData); zk.setData( "/zk-huey", "world".getBytes(), -1, new AsyncCallback.StatCallback() { @Override public void processResult(int rc, String path, Object ctx, Stat stat) { System.out.println("ResultCode: " + rc); System.out.println("ZNode: " + path); System.out.println("Context: " + ctx); System.out.println("Stat: " + stat); } }, "The Context" ); zk.close(); } }
七、判断节点是否存在
1. 使用同步API判断节点是否存在
package com.huey.dream.demo; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.AsyncCallback; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooDefs.Ids; import org.apache.zookeeper.data.Stat; /** * 使用同步API判断节点是否存在 * @author huey * @version 1.0 * @created 2015-3-1 */ public class ZKDemo { public static void main(String[] args) throws Exception { final CountDownLatch connectedSignal = new CountDownLatch(1); final ZooKeeper zk = new ZooKeeper("192.168.1.109:2182", 5000, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == KeeperState.SyncConnected) { if (event.getType() == EventType.None && event.getPath() == null) { connectedSignal.countDown(); } } } }); connectedSignal.await(); Stat stat = zk.exists("/zk-huey", false); if (stat == null) { zk.create("/zk-huey", "hello".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } else { System.out.println("Stat: " + stat); } zk.close(); } }
2. 使用异步API判断节点是否存在
package com.huey.dream.demo; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.AsyncCallback; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.data.Stat; /** * 使用异步API判断节点是否存在 * @author huey * @version 1.0 * @created 2015-3-1 */ public class ZKDemo { public static void main(String[] args) throws Exception { final CountDownLatch connectedSignal = new CountDownLatch(1); final ZooKeeper zk = new ZooKeeper("192.168.1.109:2182", 5000, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == KeeperState.SyncConnected) { if (event.getType() == EventType.None && event.getPath() == null) { connectedSignal.countDown(); } } } }); connectedSignal.await(); zk.exists( "/zk-huey", false, new AsyncCallback.StatCallback() { @Override public void processResult(int rc, String path, Object ctx, Stat stat) { System.out.println("ResultCode: " + rc); System.out.println("ZNode: " + path); System.out.println("Context: " + ctx); System.out.println("Stat: " + stat); } }, "The Context" ); zk.close(); } }
八、权限控制
package com.huey.dream.demo; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.ZooDefs.Ids; /** * ZooKeeper权限控制 * @author huey * @version 1.0 * @created 2015-3-1 */ public class ZKDemo { public static void main(String[] args) throws Exception { /** * 使用含有权限信息的zookeeper会话创建数据节点 */ final CountDownLatch connectedSignal = new CountDownLatch(1); ZooKeeper zk = new ZooKeeper("192.168.1.109:2182", 5000, new Watcher() { @Override public void process(WatchedEvent event) { connectedSignal.countDown(); } }); connectedSignal.await(); zk.addAuthInfo("digest", "huey:123".getBytes()); zk.create("/zk-huey", "hello".getBytes(), Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT); zk.close(); /** * 使用无权限信息的zookeeper会话访问含有权限信息的数据节点 */ try { final CountDownLatch signal = new CountDownLatch(1); ZooKeeper zk1 = new ZooKeeper("192.168.1.109:2182", 5000, new Watcher() { @Override public void process(WatchedEvent event) { signal.countDown(); } }); signal.await(); zk1.getData("/zk-huey", false, null); System.out.println("NodeData: " + new String(zk1.getData("/zk-huey", false, null))); zk1.close(); } catch (Exception e) { System.out.println("Failed to delete Znode: " + e.getMessage()); } /** * 使用错误权限信息的zookeeper会话访问含有权限信息的数据节点 */ try { final CountDownLatch signal = new CountDownLatch(1); ZooKeeper zk2 = new ZooKeeper("192.168.1.109:2182", 5000, new Watcher() { @Override public void process(WatchedEvent event) { signal.countDown(); } }); signal.await(); zk2.addAuthInfo("digest", "huey:abc".getBytes()); System.out.println("NodeData: " + new String(zk2.getData("/zk-huey", false, null))); zk2.close(); } catch (Exception e) { System.out.println("Failed to delete Znode: " + e.getMessage()); } /** * 使用正确权限信息的zookeeper会话访问含有权限信息的数据节点 */ try { final CountDownLatch signal = new CountDownLatch(1); ZooKeeper zk3 = new ZooKeeper("192.168.1.109:2182", 5000, new Watcher() { @Override public void process(WatchedEvent event) { signal.countDown(); } }); signal.await(); zk3.addAuthInfo("digest", "huey:123".getBytes()); System.out.println("NodeData: " + new String(zk3.getData("/zk-huey", false, null))); zk3.close(); } catch (Exception e) { System.out.println("Failed to delete Znode: " + e.getMessage()); } } }
结果输出:
Failed to delete Znode: KeeperErrorCode = NoAuth for /zk-huey Failed to delete Znode: KeeperErrorCode = NoAuth for /zk-huey NodeData: hello