Zookeeper Java客户端搭建
目录
一、概述
二、环境搭建
三、创建节点
四、更新节点
五、删除节点
六、查看节点
七、查看子节点
八、总结
一、概述
Zookeeper 的Java客户端API使我们更轻松的去对zookeeper进行各种操作,如创建节点、修改节点值、删除节点等等。
客户端应该遵循以下几个步骤:
- 连接到zookeeper服务器。zookeeper服务器为客户端分配会话ID。
- 定期向服务器发送心跳。否则,zookeeper服务器将过期会话ID,客户端需要重新连接。
- 只要会话ID处于活动状态,就可以获取/设置znode。
- 所有任务完成后,断开与zookeeper服务器的连接。如果客户端长时间不活动,则zookeeper服务器将自动断开客户端。
本篇文章将会搭建一个简单的示例,来看看如何通过zookeeper客户端实现对服务端的操作。
二、环境搭建
创建一个springboot项目【zookeeper-api-demo】,导入zookeeper依赖。
【a】pom.xml
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.8</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency>
</dependencies>
【b】连接zookeeper服务器
因为连接zk服务器可能需要一些时间,我们可以使用 countDownLatch 阻塞,等待连接成功,控制台输出连接状态。
zookeeper一共有四种构造方法,根据方法参数不同:
- public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, long sessionId, byte[] sessionPasswd, boolean canBeReadOnly)
- public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, long sessionId, byte[] sessionPasswd)
- public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, boolean canBeReadOnly)
- ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)
参数说明如下:
- connectSstring:连接服务器列表,以“,”分割;
- sessionTimeout:心跳检测时间周期(毫秒);‘
- wather:事件监听处理通知器;
- canBeReadOnly:标识当前会话是否支持只读;
- sessionld和sessionPasswd:提供连接zookeeper的sessionld和密码, 通过这两个确定唯一一台客户端,目的是可以提供重复会话;
这里我们使用最简单的带三个参数的构造方法创建一个zookeeper对象:
package com.wsh.zookeeper.zookeeperapidemo.zookeper;import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.IOException;
import java.util.concurrent.CountDownLatch;/*** @Description: zookeeper java客户端测试* @author: weishihuai*/
public class ZookeeperDemo {/*** zookeeper服务器地址*/private static final String CONNECT_STRING = "192.168.179.133:2181";/*** 会话超时时间*/private static final int SESSION_TIMEOUT = 3000;/*** 日志*/private static final Logger logger = LoggerFactory.getLogger(ZookeeperDemo.class);public static void main(String[] args) {//门闩CountDownLatch countDownLatch = new CountDownLatch(1);try {//创建zookeeper连接ZooKeeper zooKeeper = new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, watchedEvent -> {//获取事件的状态Watcher.Event.KeeperState keeperState = watchedEvent.getState();Watcher.Event.EventType eventType = watchedEvent.getType();//如果是建立连接if (Watcher.Event.KeeperState.SyncConnected == keeperState) {if (Watcher.Event.EventType.None == eventType) {logger.info("连接zookeeper成功...");//收到服务端的响应,表示连接zookeeper成功,同时发送信号量,计数器减一,让await阻塞程序继续往下执行countDownLatch.countDown();}}});//阻塞程序countDownLatch.await();logger.info("客户端连接状态: {}", zooKeeper.getState());} catch (IOException | InterruptedException e) {e.printStackTrace();}}
}
运行main方法,结果如下:
11:23:59.299 [main-EventThread] INFO com.wsh.zookeeper.zookeeperapidemo.zookeper.ZookeeperDemo - 连接zookeeper成功...
11:23:59.299 [main] INFO com.wsh.zookeeper.zookeeperapidemo.zookeper.ZookeeperDemo - 客户端连接状态: CONNECTED
可以看到,我们成功连接到zookeeper服务器端,下面就可以进行创建节点、修改节点、删除节点等操作了。
三、创建节点
创建节点主要分为同步方式和异步方式进行创建:
- create(String path, byte[] data, List<ACL> acl, CreateMode createMode) // 同步方式
- create(String path, byte[] data, List<ACL> acl, CreateMode createMode,AsyncCallback.StringCallback callBack,Object ctx) // 异步方式
参数说明如下:
- path - znode路径;
- data - 要存储在指定znode路径中的数据;
- acl - 要创建的节点的访问控制列表。zookeeper API提供了一个静态接口ZooDefs.Ids 来获取一些基本的acl列表;
- createMode - 节点的类型,这是一个枚举,提供四种节点类型:
- PERSISTENT (持久节点)
- PERSISTENT_SEQUENTIAL (持久顺序节点)
- EPHEMERAL (临时节点)
- EPHEMERAL_SEQUENTIAL (临时顺序节点)
- callBack - 异步回调接口;
- ctx - 传递上下文参数;
案例:
首先在命令行创建/create父节点:
[zk: localhost:2181(CONNECTED) 19] create /create "create"
Created /create
[zk: localhost:2181(CONNECTED) 20] ls /
[zookeeper, create]
package com.wsh.zookeeper.zookeeperapidemo.zookeper;import org.apache.zookeeper.*;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class ZookeeperCreate {/*** zookeeper服务器地址*/private static final String CONNECT_STRING = "192.168.179.133:2181";/*** 会话超时时间*/private static final int SESSION_TIMEOUT = 3000;/*** 日志*/private static final Logger logger = LoggerFactory.getLogger(ZookeeperDemo.class);/*** zookeeper对象*/private static ZooKeeper zooKeeper = null;static {//创建zookeeper连接try {zooKeeper = new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, new CustomWatcher());} catch (IOException e) {e.printStackTrace();}}void createNode01() {try {/*** create(String path, byte[] data, List<ACL> acl, CreateMode createMode)* path: 节点的路径* data: 节点的数据* acl: 权限列表 world:anyone:cdrwa* createMode: 节点类型 持久化节点*/zooKeeper.create("/create/node1", "node1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);} catch (KeeperException | InterruptedException e) {e.printStackTrace();}}/*** world授权模式*/void createNode02() {// 权限列表 List<ACL> aclList = new ArrayList<>();// 授权模式和授权对象 Id id = new Id("world", "anyone");// 权限设置:crdwaaclList.add(new ACL(ZooDefs.Perms.READ, id));aclList.add(new ACL(ZooDefs.Perms.WRITE, id));aclList.add(new ACL(ZooDefs.Perms.DELETE, id));aclList.add(new ACL(ZooDefs.Perms.CREATE, id));aclList.add(new ACL(ZooDefs.Perms.ADMIN, id));try {zooKeeper.create("/create/node2", "node2".getBytes(), aclList, CreateMode.PERSISTENT);} catch (KeeperException | InterruptedException e) {e.printStackTrace();}}/*** auth授权模式*/void createNode03() {zooKeeper.addAuthInfo("digest", "admin:123456".getBytes());// 权限列表List<ACL> aclList = new ArrayList<>();//授权模式和授权对象Id id = new Id("auth", "admin");// 权限设置aclList.add(new ACL(ZooDefs.Perms.READ, id));try {zooKeeper.create("/create/node3", "node3".getBytes(), aclList, CreateMode.PERSISTENT);} catch (KeeperException | InterruptedException e) {e.printStackTrace();}}/*** digest授权模式*/void createNode04() {// 权限列表List<ACL> aclList = new ArrayList<>();// 授权模式和授权对象Id id = new Id("digest", "admin:0uek/hZ/V9fgiM35b0Z2226acMQ=");// 权限设置aclList.add(new ACL(ZooDefs.Perms.ALL, id));try {zooKeeper.create("/create/node4", "node4".getBytes(), aclList, CreateMode.PERSISTENT);} catch (KeeperException | InterruptedException e) {e.printStackTrace();}}/*** 异步方式创建节点*/void createNode05() {Map<String, Object> callbackParams = new HashMap<>(16);callbackParams.put("name", "wsh");zooKeeper.create("/create/node5", "node5".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT, new AsyncCallback.StringCallback() {@Overridepublic void processResult(int rc, String path, Object ctx, String name) {//rc: 0 代表创建成功//path: 节点路径//ctx: 上下文参数//name: 节点路径logger.info("rc : {}", rc);logger.info("path : {}", path);logger.info("ctx : {}", ctx);logger.info("name : {}", name);}}, callbackParams);try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}}public static void main(String[] args) {ZookeeperCreate zookeeperCreate = new ZookeeperCreate();zookeeperCreate.createNode01();zookeeperCreate.createNode02();zookeeperCreate.createNode03();zookeeperCreate.createNode04();zookeeperCreate.createNode05();}static class CustomWatcher implements Watcher {@Overridepublic void process(WatchedEvent watchedEvent) {if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {System.out.println("连接创建成功!");}}}}
然后打开终端查看对应节点是否创建成功:
[zk: localhost:2181(CONNECTED) 21] ls /
[zookeeper, create]
[zk: localhost:2181(CONNECTED) 22] ls /create
[node4, node5, node2, node3, node1]
[zk: localhost:2181(CONNECTED) 23] get /create/node1
node1
cZxid = 0x8f
ctime = Mon Dec 21 15:32:38 CST 2020
mZxid = 0x8f
mtime = Mon Dec 21 15:32:38 CST 2020
pZxid = 0x8f
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
[zk: localhost:2181(CONNECTED) 24] get /create/node2
node2
cZxid = 0x90
ctime = Mon Dec 21 15:32:38 CST 2020
mZxid = 0x90
mtime = Mon Dec 21 15:32:38 CST 2020
pZxid = 0x90
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
[zk: localhost:2181(CONNECTED) 25] get /create/node3
node3
cZxid = 0x91
ctime = Mon Dec 21 15:32:38 CST 2020
mZxid = 0x91
mtime = Mon Dec 21 15:32:38 CST 2020
pZxid = 0x91
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
[zk: localhost:2181(CONNECTED) 26] get /create/node4
node4
cZxid = 0x92
ctime = Mon Dec 21 15:32:38 CST 2020
mZxid = 0x92
mtime = Mon Dec 21 15:32:38 CST 2020
pZxid = 0x92
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
[zk: localhost:2181(CONNECTED) 27] get /create/node5
node5
cZxid = 0x93
ctime = Mon Dec 21 15:32:38 CST 2020
mZxid = 0x93
mtime = Mon Dec 21 15:32:38 CST 2020
pZxid = 0x93
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
四、更新节点
zookeeper中,跟创建节点一样,同样支持同步和异步两种方式更新节点的值:
- setData(String path, byte[] data, int version) // 同步方式
- setData(String path, byte[] data, int version,AsyncCallback.StatCallback callBack, Object ctx) // 异步方式
参数说明如下:
- path - znode路径;
- data - 要存储在指定znode路径中的数据;
- version - znode的当前版本。每当数据更改时,ZooKeeper会更新znode的版本号;
- callBack - 异步回调接口;
- ctx - 传递上下文参数;
案例:
首先得在终端上创建两个节点:
[zk: localhost:2181(CONNECTED) 29] create /set "set"
Created /set
[zk: localhost:2181(CONNECTED) 30] create /set/node1 "node1"
Created /set/node1
[zk: localhost:2181(CONNECTED) 31] create /set/node2 "node2"
Created /set/node2
[zk: localhost:2181(CONNECTED) 32] ls /set
[node2, node1]
package com.wsh.zookeeper.zookeeperapidemo.zookeper;import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.IOException;public class ZookeeperUpdate {/*** zookeeper服务器地址*/private static final String CONNECT_STRING = "192.168.179.133:2181";/*** 会话超时时间*/private static final int SESSION_TIMEOUT = 3000;/*** 日志*/private static final Logger logger = LoggerFactory.getLogger(ZookeeperDemo.class);/*** zookeeper对象*/private static ZooKeeper zooKeeper = null;static {//创建zookeeper连接try {zooKeeper = new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, new CustomWatcher());} catch (IOException e) {e.printStackTrace();}}void set01() {try {/*** setData(String path, byte[] data, int version)* path: 节点的路径* data: 节点更新值* version: 节点版本号 -1代表版本号不作为修改条件*/zooKeeper.setData("/set/node1", "node11".getBytes(), -1);} catch (KeeperException | InterruptedException e) {e.printStackTrace();}}void set02() {zooKeeper.setData("/set/node2", "node22".getBytes(), -1, new AsyncCallback.StatCallback() {@Overridepublic void processResult(int rc, String path, Object ctx, Stat stat) {// 0 代表修改成功logger.info("rc: {}", rc);// 节点路径logger.info("path: {}", path);// 上下文参数logger.info("ctx: {}", ctx);// 节点属性信息logger.info("version: {}", stat.getVersion());logger.info("ctime: {}", stat.getCtime());}}, "this is callback params");try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}}public static void main(String[] args) {ZookeeperUpdate zookeeperUpdate = new ZookeeperUpdate();zookeeperUpdate.set01();zookeeperUpdate.set02();}static class CustomWatcher implements Watcher {@Overridepublic void process(WatchedEvent watchedEvent) {if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {System.out.println("连接创建成功!");}}}}
运行程序,我们通过终端查看节点的值是否更新成功:
[zk: localhost:2181(CONNECTED) 33] get /set/node1
node11
cZxid = 0x96
ctime = Mon Dec 21 16:25:57 CST 2020
mZxid = 0x99
mtime = Mon Dec 21 16:28:38 CST 2020
pZxid = 0x96
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
[zk: localhost:2181(CONNECTED) 34] get /set/node2
node22
cZxid = 0x97
ctime = Mon Dec 21 16:26:04 CST 2020
mZxid = 0x9a
mtime = Mon Dec 21 16:28:38 CST 2020
pZxid = 0x97
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
可见,节点的值成功更新。
五、删除节点
zookeeper删除节点同样直接两种方式:同步方式和异步方式。
- delete(String path, int version) // 同步方式
- delete(String path, int version, AsyncCallback.VoidCallback callBack, Object ctx) // 异步方式
参数说明如下:
- path - 节点路径;
- version - 节点数据的当前版本;
- callBack - 异步回调接口;
- ctx - 异步回调上下文参数;
案例:
首先终端上面创建两个节点:
[zk: localhost:2181(CONNECTED) 36] create /delete "delete"
Created /delete
[zk: localhost:2181(CONNECTED) 37] create /delete/node1 "node1"
Created /delete/node1
[zk: localhost:2181(CONNECTED) 38] create /delete/node2 "node2"
Created /delete/node2
package com.wsh.zookeeper.zookeeperapidemo.zookeper;import org.apache.zookeeper.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.IOException;public class ZookeeperDelete {/*** zookeeper服务器地址*/private static final String CONNECT_STRING = "192.168.179.133:2181";/*** 会话超时时间*/private static final int SESSION_TIMEOUT = 3000;/*** 日志*/private static final Logger logger = LoggerFactory.getLogger(ZookeeperDemo.class);/*** zookeeper对象*/private static ZooKeeper zooKeeper = null;static {//创建zookeeper连接try {zooKeeper = new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, new CustomWatcher());} catch (IOException e) {e.printStackTrace();}}/*** 同步方式*/void delete01() {try {/*** delete(String path, int version)* path: 节点路径* version: 节点数据版本号*/zooKeeper.delete("/delete/node1", -1);} catch (InterruptedException | KeeperException e) {e.printStackTrace();}}/*** 异步方式*/void delete02() {zooKeeper.delete("/delete/node2", -1, new AsyncCallback.VoidCallback() {@Overridepublic void processResult(int rc, String path, Object ctx) {// 0代表删除成功logger.info("rc: {}", rc);// 节点的路径logger.info("path: {}", path);// 上下文参数对象logger.info("ctx: {}", ctx);}}, "this is callback params");try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}}public static void main(String[] args) {ZookeeperDelete zookeeperDelete = new ZookeeperDelete();zookeeperDelete.delete01();zookeeperDelete.delete02();}static class CustomWatcher implements Watcher {@Overridepublic void process(WatchedEvent watchedEvent) {if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {System.out.println("连接创建成功!");}}}}
运行程序,执行完后,使用终端查看节点是否已删除:
[zk: localhost:2181(CONNECTED) 39] ls /delete
[]
六、查看节点
在zookeeper中,查看节点同样支持同步和异步方式。
- getData(String path, boolean b, Stat stat) // 同步方式
- getData(String path, boolean b,AsyncCallback.DataCallback callBack,Object ctx) // 异步方式
参数说明:
- path - znode路径;
- b - 是否使用连接对象中注册的监视器;
- stat - 返回znode的元数据;
- callBack - 异步回调接口;
- ctx - 传递上下文参数;
案例:
首先使用终端创建两个节点:
[zk: localhost:2181(CONNECTED) 40] create /read "read"
Created /read
[zk: localhost:2181(CONNECTED) 41] create /read/node1 "node1"
Created /read/node1
[zk: localhost:2181(CONNECTED) 42] create /read/node2 "node2"
Created /read/node2
[zk: localhost:2181(CONNECTED) 43] ls /read
[node2, node1]
package com.wsh.zookeeper.zookeeperapidemo.zookeper;import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.IOException;public class ZookeeperRead {/*** zookeeper服务器地址*/private static final String CONNECT_STRING = "192.168.179.133:2181";/*** 会话超时时间*/private static final int SESSION_TIMEOUT = 3000;/*** 日志*/private static final Logger logger = LoggerFactory.getLogger(ZookeeperDemo.class);/*** zookeeper对象*/private static ZooKeeper zooKeeper = null;static {//创建zookeeper连接try {zooKeeper = new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, new CustomWatcher());} catch (IOException e) {e.printStackTrace();}}/*** 同步方式*/void read01() {try {Stat stat = new Stat();byte[] data = zooKeeper.getData("/read/node1", false, stat);logger.info("data :{}", new String(data));logger.info("version :{}", stat.getVersion());logger.info("ctime :{}", stat.getCtime());} catch (KeeperException | InterruptedException e) {e.printStackTrace();}}/*** 异步方式*/void read02() {zooKeeper.getData("/read/node2", false, new AsyncCallback.DataCallback() {@Overridepublic void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {// 0代表读取成功logger.info("rc :{}", rc);// 节点的路径logger.info("path :{}", path);// 上下文参数对象logger.info("ctx :{}", ctx);// 数据logger.info("data :{}", new String(data));// 属性对象logger.info("version :{}", stat.getVersion());}}, "this is callback params");try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}}public static void main(String[] args) {ZookeeperRead zookeeperRead = new ZookeeperRead();zookeeperRead.read01();zookeeperRead.read02();}static class CustomWatcher implements Watcher {@Overridepublic void process(WatchedEvent watchedEvent) {if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {System.out.println("连接创建成功!");}}}}
观察后端日志,可以看到,成功读取到节点的数据。
16:46:35.429 [main-EventThread] INFO com.wsh.zookeeper.zookeeperapidemo.zookeper.ZookeeperDemo - rc :0
16:46:35.429 [main-EventThread] INFO com.wsh.zookeeper.zookeeperapidemo.zookeper.ZookeeperDemo - path :/read/node2
16:46:35.429 [main-EventThread] INFO com.wsh.zookeeper.zookeeperapidemo.zookeper.ZookeeperDemo - ctx :this is callback params
16:46:35.429 [main-EventThread] INFO com.wsh.zookeeper.zookeeperapidemo.zookeper.ZookeeperDemo - data :node2
16:46:35.429 [main-EventThread] INFO com.wsh.zookeeper.zookeeperapidemo.zookeper.ZookeeperDemo - version :0
七、查看子节点
- getChildren(String path, boolean b) // 同步方式
- getChildren(String path, boolean b,AsyncCallback.ChildrenCallback callBack,Object ctx) // 异步方式
参数说明如下:
- path - Znode路径;
- b - 是否使用连接对象中注册的监视器;
- callBack - 异步回调接口;
- ctx - 传递上下文参数;
案例:
首先在终端创建两个节点:
[zk: localhost:2181(CONNECTED) 44] create /children "children"
Created /children
[zk: localhost:2181(CONNECTED) 45] create /children/node1 "node1"
Created /children/node1
[zk: localhost:2181(CONNECTED) 46] create /children/node2 "node2"
Created /children/node2
[zk: localhost:2181(CONNECTED) 47] ls /children
[node2, node1]
package com.wsh.zookeeper.zookeeperapidemo.zookeper;import org.apache.zookeeper.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.IOException;
import java.util.List;public class ZookeeperChildren {/*** zookeeper服务器地址*/private static final String CONNECT_STRING = "192.168.179.133:2181";/*** 会话超时时间*/private static final int SESSION_TIMEOUT = 3000;/*** 日志*/private static final Logger logger = LoggerFactory.getLogger(ZookeeperDemo.class);/*** zookeeper对象*/private static ZooKeeper zooKeeper = null;static {//创建zookeeper连接try {zooKeeper = new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, new CustomWatcher());} catch (IOException e) {e.printStackTrace();}}/*** 同步方式*/void getChildren01() {List<String> children;try {children = zooKeeper.getChildren("/children", false);for (String child : children) {logger.info("节点:" + child);}} catch (KeeperException | InterruptedException e) {e.printStackTrace();}}/*** 异步方式*/void getChildren02() {zooKeeper.getChildren("/children", false, new AsyncCallback.ChildrenCallback() {@Overridepublic void processResult(int rc, String path, Object ctx, List<String> children) {// 0代表读取成功logger.info("rc :{}", rc);// 节点的路径logger.info("path :{}", path);// 上下文参数对象logger.info("ctx :{}", ctx);for (String child : children) {logger.info("节点:" + child);}}}, "this is callback params");try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}}public static void main(String[] args) {ZookeeperChildren zookeeperChildren = new ZookeeperChildren();zookeeperChildren.getChildren01();zookeeperChildren.getChildren02();}static class CustomWatcher implements Watcher {@Overridepublic void process(WatchedEvent watchedEvent) {if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {System.out.println("连接创建成功!");}}}}
观察后端日志,可见成功查询出节点对应的所有子节点信息:
16:54:08.926 [main] INFO com.wsh.zookeeper.zookeeperapidemo.zookeper.ZookeeperDemo - 节点:node2
16:54:08.926 [main] INFO com.wsh.zookeeper.zookeeperapidemo.zookeper.ZookeeperDemo - 节点:node1
16:54:08.928 [main-SendThread(192.168.179.133:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Reading reply sessionid:0x1000003ec2f000a, packet:: clientPath:/children serverPath:/children finished:false header:: 2,8 replyHeader:: 2,171,0 request:: '/children,F response:: v{'node2,'node1}
16:54:08.929 [main-EventThread] INFO com.wsh.zookeeper.zookeeperapidemo.zookeper.ZookeeperDemo - rc :0
16:54:08.930 [main-EventThread] INFO com.wsh.zookeeper.zookeeperapidemo.zookeper.ZookeeperDemo - path :/children
16:54:08.930 [main-EventThread] INFO com.wsh.zookeeper.zookeeperapidemo.zookeper.ZookeeperDemo - ctx :this is callback params
16:54:08.930 [main-EventThread] INFO com.wsh.zookeeper.zookeeperapidemo.zookeper.ZookeeperDemo - 节点:node2
16:54:08.930 [main-EventThread] INFO com.wsh.zookeeper.zookeeperapidemo.zookeper.ZookeeperDemo - 节点:node1
八、总结
本篇文章主要总结了我们如何使用原生API去连接zookeeper服务器端,然后使用客户端API去进行一些操作,如新增节点、修改节点等。当然还有一些开源框架对zookeeper进行了封装,如Curator,它解决了很多 Zookeeper 客户端非常底层的细节开发工作,包括连接重连、反复注册 Watcher 和 NodeExistsException 异常等,感兴趣的小伙伴可以去学习一下。
Zookeeper Java客户端搭建相关推荐
- Zookeeper Java 客户端 ——Apache Curator
Zookeeper Java 客户端 --Apache Curator 一.基本依赖 二.客户端相关操作 2.1 创建客户端实例 2.2 重试策略 ...
- 2.ZooKeeper客户端Curator「第三章 ZooKeeper Java客户端」「架构之路ZooKeeper理论和实战」
前言 上一篇文章 介绍了zookeeper原生API的使用,使用过原生API不得不说,有很多的问题,比如:不能递归创建和删除节点.Watcher只能使用一次.还有很多可以解决分布式应用问题的api(比 ...
- Zookeeper java客户端ZkClient使用详解
简介 ZKClient是一个Zookeeper客户端框架,是对Zookeeper原生API的封装.使得使用更方便.功能更多. 查看之前必须要对Zookeeper的基本命令操作.Watch机制.Acl等 ...
- zookeeper Java客户端API的使用方法
1.创建会话 2.创建节点(异步.同步) 3.删除节点(异步.同步) 4.读取数据(异步.同步) 5.节点检测(异步.同步) 6.更新数据(异步.同步) 7.ACL权限控制 演示代码下载(代码来自极客 ...
- zookeeper集群搭建和API使用
一.vmware设置虚拟机centeros的ip 1.设置vm属性 先设置NAT模式 点击菜单栏编辑 记录子网网关地址 2.修改linux配置 [1]修改linux ip地址 vi /etc/sysc ...
- idea zookeeper插件使用_zookeeper的Java客户端操作
客户端选择 zookeeper的Java客户端主要有zkclient和Curator,此篇文章介绍Curator,就冲他官网的简介,zookeeper书的作者Patrick Hunt给了这么高的评价: ...
- ZooKeeper学习总结(2)——ZooKeeper开源Java客户端ZkClient使用
zkclient是zookeeper的Java客户端.它让Zookeeper API 使用起来更简单:它非常方便订阅各种事件并自动重新绑定事件(会话建立.节点修改.节点删除.子节点变更等):它提供了s ...
- 【Java从0到架构师】Zookeeper 应用 - Java 客户端操作、服务器动态感知、分布式锁业务处理
分布式基石 Zookeeper 框架全面剖析 Java 客户端操作 Java 客户端 API 服务器的动态感知 服务注册 服务发现 分布式锁业务处理 单机环境(一个虚拟机中) 分布式环境_同名节点 分 ...
- ZooKeeper :Java客户端Watcher API介绍
ZooKeeper :Java客户端Watcher API介绍 在上一篇博客中,博主给大家介绍了Java客户端的Session.ACL以及Znode API: ZooKeeper :Java客户端Se ...
- Zookeeper的java客户端Curator
Zookeeper的java客户端Curator 常见的zookeeper java API: Curator API 常用操作 建立连接 添加节点 删除节点 修改节点 查询节点 watch事件监听 ...
最新文章
- FMDatabase常见的几个操作
- JSON 是个什么??!!!
- vim打开所有折叠的方法及其他所有折叠的命令
- POJ1182--带权并查集
- python电子英汉词典显示_python网页抓取之英汉字典
- C#中This的用法
- 零基础如何入门MATLAB(适用于所有编程语言)?(建议收藏)
- excel宏教程_综合 | 如何使用Excel按条件高效查找数据?
- 2017年中国网络安全报告
- ThinkPHP微信小说小程序源码-自带采集带安装教程
- python能开发小程序吗_微信小程序用什么语言开发?Python能开发小程序么
- 第 342 场力扣周赛
- 获取微信公众号临时素材音频并转war格式
- java dozer,MapStruct相当于提示(Dozer)?
- 「设计模式(五) - 代理模式」
- Python的列表与操作
- 数学不好是原罪——凸优化学习笔记(个人学习记录汇总)
- 自定义表单、自定义流程、自定义页面、自定义报表应用开发平台
- Java程序员职业规划如何做?发展方向有哪些?
- java 计算星座_java 根据生日计算星座