zookeeperCli和Java操作zookeeperAPI
推荐一个zookeeper可视化工具:zktools.exe
eclipse集成的工具: http://www.massedynamic.org/eclipse/updates/
1.zkCli客户端基本操作(命令行操作)
1.链接并查看基本命令
.\zkCli.cmd -server 127.0.0.1:
其基本命令如下
ZooKeeper -server host:port cmd args
stat path [watch]
set path data [version]
ls path [watch]
delquota [-n|-b] path
ls2 path [watch]
setAcl path acl
setquota -n|-b val path
history
redo cmdno
printwatches on|off
delete path [version]
sync path
listquota path
rmr path
get path [watch]
create [-s] [-e] path data acl
addauth scheme auth
quit
getAcl path
close
connect host:port
2.创建Znodes--- create
用给定的路径创建一个znode。flag参数指定创建的znode是临时的,持久的还是顺序的。默认情况下,所有znode都是持久的。
-e 参数指定是临时节点:当会话过期或客户端断开连接时,临时节点(flag:-e)将被自动删除。
-s 参数指定是顺序节点。 顺序节点保证znode路径将是唯一的。 ZooKeeper集合将向znode路径填充10位序列号。例如,znode路径 /myapp 将转换为/myapp0000000001,下一个序列号将为/myapp0000000002。如果没有指定flag,则znode被认为是持久的。
语法
create /path /data
(1)创建永久节点(值的引号可有可无)
[zk: 127.0.0.1:(CONNECTED) ] create /test "testValue"
Created /test
(2)创建临时节点 加-e参数
[zk: 127.0.0.1:(CONNECTED) ] create -e /temp "tempValue"
Created /temp
(3)创建顺序节点 加 -s 参数
[zk: 127.0.0.1:(CONNECTED) ] create -s /queue "tqueueValue"
Created /queue0000000003
(4)创建临时顺序节点 加 -s -e 参数
[zk: 127.0.0.1:(CONNECTED) ] create -s -e /queueTmp "queueTmpValue"
Created /queueTmp0000000004
注意:
(1)创建子节点的时候不能跨目录创建节点,也就是子节点必须在父节点存在的情况下创建。由于test22不存在所以第二个创建失败
[zk: 127.0.0.1:(CONNECTED) ] create /test/children1 "testChildrenValue"
Created /test/children1
[zk: 127.0.0.1:(CONNECTED) ] create /test22/children1 "testChildrenValue"
Node does not exist: /test22/children1
(2)重复创建会失败
[zk: 127.0.0.1:(CONNECTED) ] create /test "tttt"
Node already exists: /test
查看上面创建的节点:
[zk: 127.0.0.1:(CONNECTED) ] ls /
[queue0000000003, temp, zookeeper, test, queueTmp0000000004, FirstZnode]
[zk: 127.0.0.1:(CONNECTED) ] ls /test
[children1]
补充:如果想创建值为空的节点可以:
[zk: 127.0.0.1:2181(CONNECTED) 119] create /null ""
Created /null
3.获取数据---get
语法
get /path
它返回znode的关联数据和指定znode的元数据。你将获得信息,例如上次修改数据的时间,修改的位置以及数据的相关信息。此CLI还用于分配监视器以显示数据相关的通知。要访问顺序节点,必须输入znode的完整路径。
如下:
[zk: 127.0.0.1:(CONNECTED) ] get /test
testValue
cZxid = 0x300000002
ctime = Fri Mar :: CST
mZxid = 0x300000002
mtime = Fri Mar :: CST
pZxid = 0x300000006
cversion =
dataVersion =
aclVersion =
ephemeralOwner = 0x0
dataLength =
numChildren =
[zk: 127.0.0.1:(CONNECTED) ] get /test/children1
testChildrenValue
cZxid = 0x300000006
ctime = Fri Mar :: CST
mZxid = 0x300000006
mtime = Fri Mar :: CST
pZxid = 0x300000006
cversion =
dataVersion =
aclVersion =
ephemeralOwner = 0x0
dataLength =
numChildren =
[zk: 127.0.0.1:(CONNECTED) ] get /queueTmp0000000004
queueTmpValue
cZxid = 0x300000005
ctime = Fri Mar :: CST
mZxid = 0x300000005
mtime = Fri Mar :: CST
pZxid = 0x300000005
cversion =
dataVersion =
aclVersion =
ephemeralOwner = 0x10038e5aa8c0000
dataLength =
numChildren =
4. Watch 监视节点
当指定的znode或znode的子数据更改时,监视器会显示通知。你只能在 get 命令中设置watch。
语法:
get /path [watch]
例如:
[zk: 127.0.0.1:(CONNECTED) ] get /test
testValue
cZxid = 0x300000002
ctime = Fri Mar :: CST
mZxid = 0x300000002
mtime = Fri Mar :: CST
pZxid = 0x300000006
cversion =
dataVersion =
aclVersion =
ephemeralOwner = 0x0
dataLength =
numChildren =
输出类似于普通的 get 命令,但它会等待后台等待znode更改。<从这里开始>
5. 设置数据(相当于修改值)---set
设置指定znode的数据。完成此设置操作后,你可以使用 get CLI命令检查数据。如果你在 get 命令中分配了watch选项(如上一个命令),则输出监视信息
语法
set /path /data
例如:
[zk: 127.0.0.1:(CONNECTED) ] set /test tttt WATCHER::
cZxid = 0x300000002
WatchedEvent state:SyncConnected type:NodeDataChanged path:/test ctime = Fri Mar :: CST
mZxid = 0x300000009
mtime = Fri Mar :: CST
pZxid = 0x300000006
cversion =
dataVersion =
aclVersion =
ephemeralOwner = 0x0
dataLength =
numChildren =
[zk: 127.0.0.1:(CONNECTED) ] get /test
tttt
cZxid = 0x300000002
ctime = Fri Mar :: CST
mZxid = 0x300000009
mtime = Fri Mar :: CST
pZxid = 0x300000006
cversion =
dataVersion =
aclVersion =
ephemeralOwner = 0x0
dataLength =
numChildren =
6.列出节点---ls
此命令用于列出和显示znode的子项。
语法:
ls /path
例如:
[zk: 127.0.0.1:(CONNECTED) ] ls /
[queue0000000003, temp, zookeeper, test, queueTmp0000000004, FirstZnode]
[zk: 127.0.0.1:(CONNECTED) ] ls /test
[children1]
[zk: 127.0.0.1:(CONNECTED) ] ls /test/children1
[]
7.检查状态---stat
状态描述指定的znode的元数据。它包含时间戳,版本号,ACL,数据长度和子znode等细项。
语法:
stat /path
例如:
[zk: 127.0.0.1:(CONNECTED) ] stat /test
cZxid = 0x300000002
ctime = Fri Mar :: CST
mZxid = 0x300000009
mtime = Fri Mar :: CST
pZxid = 0x300000006
cversion =
dataVersion =
aclVersion =
ephemeralOwner = 0x0
dataLength =
numChildren =
8.移除Znode---rmr(有节点也可以删)
移除指定的znode并递归其所有子节点。只有在这样的znode可用的情况下才会发生。有子节点删除父节点是可以删除成功的。
语法:
rmr /path
例如:
[zk: 127.0.0.1:(CONNECTED) ] rmr /temp
[zk: 127.0.0.1:(CONNECTED) ] ls /
[queue0000000003, zookeeper, test, queueTmp0000000004, FirstZnode]
[zk: 127.0.0.1:(CONNECTED) ] rmr /test
[zk: 127.0.0.1:(CONNECTED) ] ls /
[queue0000000003, zookeeper, queueTmp0000000004, FirstZnode]
9.删除节点---delete(只能删除没有子节点的节点)
语法:
delete /path
例如:
[zk: 127.0.0.1:(CONNECTED) ] ls /
[]
[zk: 127.0.0.1:(CONNECTED) ] delete /
Node not empty: /
[zk: 127.0.0.1:(CONNECTED) ] delete //
[zk: 127.0.0.1:(CONNECTED) ] delete /
[zk: 127.0.0.1:(CONNECTED) ] ls /
[queue0000000003, zookeeper, queueTmp0000000004, FirstZnode]
2.Java连接zookeeper进行操作API
maven坐标:
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.8</version>
</dependency>
1.基础知识
与ZooKeeper集合进行交互的应用程序称为 ZooKeeper客户端或简称客户端。
客户端应该遵循以步骤,与ZooKeeper集合进行清晰和干净的交互。
(1)连接到ZooKeeper集合。ZooKeeper集合为客户端分配会话ID。
(2)定期向服务器发送心跳。否则,ZooKeeper集合将过期会话ID,客户端需要重新连接。
(3)只要会话ID处于活动状态,就可以获取/设置znode。
(4)所有任务完成后,断开与ZooKeeper集合的连接。如果客户端长时间不活动,则ZooKeeper集合将自动断开客户端。
(1)zookeeper客户端与zookeeper server连接的状态有下面几种:
KeeperState.Expired 客户端和服务器在ticktime的时间周期内,是要发送心跳通知的。这是租约协议的一个实现。客户端发送request,告诉服务器其上一个租约时间,服务器收到这个请求后,告诉客户端其下一个租约时间是哪个时间点。当客户端时间戳达到最后一个租约时间,而没有收到服务器发来的任何新租约时间,即认为自己下线(此后客户端会废弃这次连接,并试图重新建立连接)。这个过期状态就是Expired状态
KeeperState.Disconnected 就像上面那个状态所述,当客户端断开一个连接(可能是租约期满,也可能是客户端主动断开)这是客户端和服务器的连接就是Disconnected状态
KeeperState.SyncConnected 一旦客户端和服务器的某一个节点建立连接(注意,虽然集群有多个节点,但是客户端一次连接到一个节点就行了),并完成一次version、zxid的同步,这时的客户端和服务器的连接状态就是SyncConnected
KeeperState.AuthFailed zookeeper客户端进行连接认证失败时,发生该状态
需要说明的是,这些状态在触发时,所记录的事件类型都是:EventType.None
(2)事件类型WatchedEvent.getType()有下面五种:是Event的一个内部枚举类。当zookeeper客户端监听某个znode节点”/node-x”时:
public enum EventType {
None (-1),
NodeCreated (1),
NodeDeleted (2),
NodeDataChanged (3),
NodeChildrenChanged (4);
...
}
解释如下:
EventType.NodeCreated 当node-x这个节点被创建时,该事件被触发
EventType.NodeChildrenChanged 当node-x这个节点的直接子节点被创建、被删除、子节点数据发生变更时,该事件被触发。
EventType.NodeDataChanged 当node-x这个节点的数据发生变更时,该事件被触发
EventType.NodeDeleted 当node-x这个节点被删除时,该事件被触发。
EventType.None 当zookeeper客户端的连接状态发生变更时,即KeeperState.Expired、KeeperState.Disconnected、KeeperState.SyncConnected、KeeperState.AuthFailed状态切换时,描述的事件类型为EventType.None
2.Java连接zookeeper
ZooKeeper API的核心部分是ZooKeeper类。它提供了在其构造函数中连接ZooKeeper集合的选项,并具有以下方法:
connect - 连接到ZooKeeper集合
create- 创建znode
exists- 检查znode是否存在及其信息
getData - 从特定的znode获取数据
setData - 在特定的znode中设置数据
getChildren - 获取特定znode中的所有子节点
delete - 删除特定的znode及其所有子项
close - 关闭连接
ZooKeeper类通过其构造函数提供connect功能。构造函数的签名如下 :
ZooKeeper(String connectionString, int sessionTimeout, Watcher watcher)
connectionString - ZooKeeper集合主机。
sessionTimeout - 会话超时(以毫秒为单位)。
watcher - 实现“监视器”界面的对象。ZooKeeper集合通过监视器对象返回连接状态。
如下连接代码:
当然其链接地址可以改为集群:127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183
package zookeper; import java.io.IOException;
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.KeeperState;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper; public class BaseAPI {
private static ZooKeeper zoo;
final static CountDownLatch connectedSignal = new CountDownLatch(1); public static ZooKeeper connect(String host) throws IOException, InterruptedException {
zoo = new ZooKeeper(host, 5000, new Watcher() {
public void process(WatchedEvent we) {
if (we.getState() == KeeperState.SyncConnected) {
connectedSignal.countDown();
}
}
}); connectedSignal.await();
return zoo;
} public void close() throws InterruptedException {
zoo.close();
} public static void create(String path, byte[] data) throws KeeperException, InterruptedException {
zoo.create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
} public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
ZooKeeper connect = connect("127.0.0.1:2181");
System.out.println("=================连接成功===============");
}
}
解释:因为链接zookeper是一个异步的过程,所以用闭锁来阻塞主线程。
这里 CountDownLatch 用于停止(等待)主进程,直到客户端与ZooKeeper集合连接。ZooKeeper集合通过监视器回调来回复连接状态。一旦客户端与ZooKeeper集合连接,监视器回调就会被调用,并且监视器回调函数调用CountDownLatch的countDown方法来释放锁,在主进程中await。
3.创建节点:
ZooKeeper类提供了在ZooKeeper集合中创建一个新的znode的create方法。 create 方法的签名如下:
path - Znode路径。例如,/myapp1,/myapp2,/myapp1/mydata1,myapp2/mydata1/myanothersubdata
data - 要存储在指定znode路径中的数据(要转为字节数组byte[]进行存储)
acl - 要创建的节点的访问控制列表。ZooKeeper API提供了一个静态接口 ZooDefs.Ids 来获取一些基本的acl列表。例如,ZooDefs.Ids.OPEN_ACL_UNSAFE返回打开znode的acl列表。
createMode - 节点的类型,即临时,顺序或两者。这是一个枚举。
ZooKeeper connect = connect("127.0.0.1:2181");
System.out.println("=================连接成功===============");
String ret = zoo.create("/javacreate", "javacreateValue".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT);
System.out.println(ret);
结果:(可见创建节点返回的是节点的路径)
=================连接成功===============
/javacreate
重复创建节点会报错如下:
=================连接成功===============
Exception in thread "main" org.apache.zookeeper.KeeperException$NodeExistsException: KeeperErrorCode = NodeExists for /javacreate
at org.apache.zookeeper.KeeperException.create(KeeperException.java:119)
at org.apache.zookeeper.KeeperException.create(KeeperException.java:51)
at org.apache.zookeeper.ZooKeeper.create(ZooKeeper.java:783)
at zookeper.BaseAPI.main(BaseAPI.java:42)
4. Exists - 检查Znode的存在与获取数据的stat信息(可以注册监听)
ZooKeeper类提供了 exists 方法来检查znode的存在。如果指定的znode存在,则返回一个znode的元数据stat。
exists(String path, boolean watcher)
path- Znode路径
watcher - 布尔值,用于指定是否监视指定的znode
例如:
ZooKeeper connect = connect("127.0.0.1:2181");
System.out.println("=================连接成功===============");
Stat exists = connect.exists("/javacreate", true);
System.out.println(exists);
结果: (如果访问一个不存在的节点返回的是null)
=================连接成功===============
12884901917,12884901917,1552024345963,1552024345963,0,0,0,0,15,0,12884901917
stat可以获取版本以及其他有用信息
5. setData方法 修改节点
ZooKeeper类提供 setData 方法来修改指定znode中附加的数据。 setData 方法的签名如下:
setData(String path, byte[] data, int version)
path- Znode路径
data - 要存储在指定znode路径中的数据。
version- znode的当前版本。每当数据更改时,ZooKeeper会更新znode的版本号。(必须传入正确的版本)
如下:
final String path = "/javacreate";
final ZooKeeper connect = connect("127.0.0.1:2181");
System.out.println("=================连接成功===============");
Stat stat = connect.exists("/javacreate", true);
Stat setData = connect.setData("/javacreate", "vvvv222".getBytes(), stat.getVersion());
6. getChildren方法--获取所有的子节点(可以注册监听)
getChildren(String path, Watcher watcher)
path - Znode路径。
watcher - 监视器类型的回调函数。当指定的znode被删除或znode下的子节点被创建/删除时,ZooKeeper集合将进行通知。这是一次性通知。
注意:
(1)当节点不存在时直接获取会报错
(2)获取的只是下面的一级子节点,也就是对于子节点的子节点是获取不到的
(3)监听的事件也是只能监听到字目录节点的数量变化、监听不到子子目录的变化。
测试代码:
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
final String path = "/key1";
final ZooKeeper connect = connect("127.0.0.1:2181");
final CountDownLatch latch = new CountDownLatch(1);
// 获取子节点不注册监听
List<String> children2 = connect.getChildren(path, false);
System.out.println(children2); // 获取子节点注册监听
connect.getChildren(path, new Watcher() {
@Override
public void process(WatchedEvent event) {
// 1打印一下事件
System.out.println(event);
// 如果事件类型为none,且连接状态为超时就退出且闭锁减一(实际上还可以监听更多的事件,比如说节点修改、节点删除等事件并作出相应的操作)
if (event.getType() == Event.EventType.None) {
switch (event.getState()) {
case Expired:
break;
} } else {// 2如果事件类型不是NONE就打印一下事件且重新获取数据并且闭锁减一
try {
System.out.println("监听到的事件类型是:" + event.getType());
// 再次注册监听
byte[] bn = connect.getData(path, new MyWatcher(connect, path), null);
String data = new String(bn, "UTF-8");
System.out.println(data);
latch.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}); latch.await();
}
6. 删除Znode
delete(String path, int version)
path - Znode路径。
version - znode的当前版本。
注意:如果传的version不正确会报错
如下:
connect.delete("/javacreate", connect.exists(path, false).getVersion());
7. getData方法 获取数据(可以注册监听)
支持同步获取和异步获取,四个方法如下:
(1)同步获取方法
ZooKeeper类提供 getData 方法来获取附加在指定znode中的数据及其状态。 getData 方法的签名如下:
byte[] getData(String path, boolean watch, Stat stat)
byte[] getData(final String path, Watcher watcher, Stat stat)
(2)异步获取方法
void getData(final String path, Watcher watcher,
DataCallback cb, Object ctx) public void getData(String path, boolean watch, DataCallback cb, Object ctx) {
getData(path, watch ? watchManager.defaultWatcher : null, cb, ctx);
}
参数解释
path 指定数据节点的路径,获取该节点下面的子节点
watcher 注册在path上的Watcher。节点变更会通知会向客户端发起通知。
stat 指定数据节点状态信息。传入旧stat,方法执行过程中会将其替换为新stat对象。(获取方法可以用上面介绍过的exists获取)
watch 表示是否需要注册一个watcher。true:注册默认watcher,false:不需要注册watcher
cb 注册一个异步回调函数
ctx 传递上下文信息
获取数据且监听节点的测试如下:(重要)
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
final CountDownLatch latch = new CountDownLatch(1);
final String path = "/javacreate";
final ZooKeeper connect = connect("127.0.0.1:2181");
System.out.println("=================连接成功==============="); // 1.获取元数据stat
Stat znodeStat = connect.exists(path, false); // 2.同步获取数据且不监听但是覆盖stat
byte[] data = connect.getData(path, false, znodeStat);
System.out.println(new String(data, "UTF-8")); // 3.同步获取数据且监听不覆盖stat
byte[] data2 = connect.getData(path, new Watcher() {
@Override
public void process(WatchedEvent event) {
// 3.1打印一下事件
System.out.println(event);
// 如果事件类型为none,且连接状态为超时就退出且闭锁减一(实际上还可以监听更多的事件,比如说节点修改、节点删除等事件并作出相应的操作)
if (event.getType() == Event.EventType.None) {
switch (event.getState()) {
case Expired:
latch.countDown();
break;
} } else {// 3.2如果事件类型不是NONE就打印一下事件且重新获取数据并且闭锁减一
try {
System.out.println("监听到的事件类型是:" + event.getType());
byte[] bn = connect.getData(path, false, null);
String data = new String(bn, "UTF-8");
System.out.println(data);
latch.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}, null); // 阻塞等待事件变化
latch.await();
}
结果:
=================连接成功===============
22233444
WatchedEvent state:SyncConnected type:NodeDataChanged path:/javacreate
我们通过zkCli修改此节点:
[zk: 127.0.0.1:(CONNECTED) ] set /javacreate
cZxid = 0x30000001d
ctime = Fri Mar :: CST
mZxid = 0x300000053
mtime = Fri Mar :: CST
pZxid = 0x30000001d
cversion =
dataVersion =
aclVersion =
ephemeralOwner = 0x0
dataLength =
numChildren =
java监听到节点修改事件并且控制台信息变为如下:
=================连接成功===============
22233444
WatchedEvent state:SyncConnected type:NodeDataChanged path:/javacreate
监听到的事件类型是:NodeDataChanged
22233444555
补充:异步创建节点的例子
在原来的基础上增加两个参数即可,第一个是异步回调,需要实现 StringCallback 接口,最后一个接口是上下文环境。
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
final String path = "/javacreate2";
final ZooKeeper connect = connect("127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183");
connect.create(path, "111".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT,
new StringCallback() {
@Override
public void processResult(int rc, String path, Object ctx, String name) {
System.out.println("create path result:[" + rc + ", " + path + "," + ctx + ", real path name "
+ name + " ]");
}
}, "context"); Thread.sleep(10*1000);
}
结果:
create path result:[0, /javacreate2,context, real path name /javacreate2 ]
补充关于建监听做下面补充:
(1) 监控同一个节点X的一个watcher实例,通过exist、getData等注册方式多次注册的,zkClient也只会通知一次。zkClient是不是做多次watcher通知,和使用什么方法注册的没有关系,关键在于所注册的watcher实例是否为同一个实例。
(2) 当一个节点还不存在时,zk.getData这样设置的watcher是会抛出KeeperException$NoNodeException异常的,这次注册会失败,watcher也不会起作用。也就是通过getData()监听一个不存在的节点会报错如下:
Exception in thread "main" org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = NoNode for /javacreate111
at org.apache.zookeeper.KeeperException.create(KeeperException.java:111)
at org.apache.zookeeper.KeeperException.create(KeeperException.java:51)
at org.apache.zookeeper.ZooKeeper.getData(ZooKeeper.java:1212)
at zookeper.BaseAPI.main(BaseAPI.java:48)
(3)zookeeper中并没有“永久监听”这种机制。但是可以通过自行编程实现。
思路可以归为两类:一种是“在保证所有节点的watcher都被重新注册”的前提下,再进行目录、子目录的更改;另外一种是“在监听被触发后,被重新注册前,重新取一次节点的信息”确保在“监听真空期”znode没有变化。
(4)关于可监听事件与对应方法如下:(只能在下面三个方法中进行监听节点)
注册方式 | NodeCreated | NodeChildrenChanged | NodeDataChanged | EventType.NodeDeleted |
---|---|---|---|---|
zk.getChildren(“/node-x”,watcher) | 可监控 | 可监控 | ||
zk.exists(“/node-x”,watcher) | 可监控 | 可监控 | 可监控 | |
zk.getData(“/node-x”,watcher) | 可监控 | 可监控 |
补充:永久监听的一个简单实现
其实现思路就是在监听器的处理事件里面再次注册监听器,如下就是一个简单的实现:
package zookeper; import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper; public class MyWatcher implements Watcher { private ZooKeeper connect;
private String path; public MyWatcher(ZooKeeper connect, String path) {
super();
this.connect = connect;
this.path = path;
} @Override
public void process(WatchedEvent event) {
// 1打印一下事件
System.out.println(event);
// 如果事件类型为none,且连接状态为超时就退出且闭锁减一(实际上还可以监听更多的事件,比如说节点修改、节点删除等事件并作出相应的操作)
if (event.getType() == Event.EventType.None) {
switch (event.getState()) {
case Expired:
break;
} } else {// 2如果事件类型不是NONE就打印一下事件且重新获取数据并且闭锁减一
try {
System.out.println("监听到的事件类型是:" + event.getType());
// 再次注册监听
byte[] bn = connect.getData(path, new MyWatcher(connect, path), null);
String data = new String(bn, "UTF-8");
System.out.println(data);
} catch (Exception e) {
e.printStackTrace();
}
}
} }
测试代码:
final CountDownLatch latch = new CountDownLatch(1);
final String path = "/javacreate";
final ZooKeeper connect = connect("127.0.0.1:2181");
System.out.println("=================连接成功==============="); // 3.同步获取数据且监听不覆盖stat
MyWatcher myWatcher = new MyWatcher(connect, path);
connect.exists(path, myWatcher); // 阻塞
latch.await();
我们在zkCli客户端多次修改节点查看结果:
=================连接成功===============
WatchedEvent state:SyncConnected type:NodeDataChanged path:/javacreate
监听到的事件类型是:NodeDataChanged
336
WatchedEvent state:SyncConnected type:NodeDataChanged path:/javacreate
监听到的事件类型是:NodeDataChanged
336
WatchedEvent state:SyncConnected type:NodeDataChanged path:/javacreate
监听到的事件类型是:NodeDataChanged
336
WatchedEvent state:SyncConnected type:NodeDataChanged path:/javacreate
监听到的事件类型是:NodeDataChanged
336
zookeeperCli和Java操作zookeeperAPI的更多相关文章
- Java操作Sqlite数据库-jdbc连接
Java操作Sqlite数据库步骤: 1. 导入Sqlite jdbc 本文使用sqlite-jdbc-3.7.2.jar,下载地址 http://pan.baidu.com/s/1kVHAGdD 2 ...
- 【MongoDB for Java】Java操作MongoDB
上一篇文章: http://www.cnblogs.com/hoojo/archive/2011/06/01/2066426.html介绍到了在MongoDB的控制台完成MongoDB的数据操作,通过 ...
- Java操作Oracle
public class DBCon { // 数据库驱动对象 public static final String DRIVER = "oracle.jdbc.driver.OracleD ...
- JAVA操作ORACLE数据库的存储过程
一.任务提出 JAVA操作oracle11g存储过程实验需要完成以下几个实例: 1.调用没有返回参数的过程(插入记录.更新记录) 2.有返回参数的过程 3.返回列表的过程 4.返回带分页的列表的过程. ...
- JAVA操作MongoDB数据库
1. 首先,下载MongoDB对Java支持的驱动包 驱动包下载地址:https://github.com/mongodb/mongo-java-driver/downloads 2.Java操作Mo ...
- Java操作Session与Cookie
1,Java操作Session Java操作Session非常简单,步骤如下 1.1,在servlet中通过request获取session HttpSession session = request ...
- JAVA操作COOKIE
JAVA操作COOKIE 1.设置Cookie Cookie cookie = new Cookie("key", "value"); cookie.setMa ...
- [转]MongoDB for Java】Java操作MongoDB
原文地址: MongoDB for Java]Java操作MongoDB 开发环境: System:Windows IDE:eclipse.MyEclipse 8 Database:mongoDB 开 ...
- Java操作文件夹的工具类
Java操作文件夹的工具类 import java.io.File; public class DeleteDirectory { /** * 删除单个文件 * @param fileName 要删除 ...
随机推荐
- 最短路经算法简介(Dijkstra算法,A*算法,D*算法)
据 Drew 所知最短路经算法现在重要的应用有计算机网络路由算法,机器人探路,交通路线导航,人工智能,游戏设计等等.美国火星探测器核心的寻路算法就是采用的D*(D Star)算法. 最短路经计算分静态 ...
- pxc5.7配置安装
pxc5.7配置安装 一.准备工作 # Centos6. 最小化安装操作系统 ########################---- Centos最小化安装推荐常用依赖包---- ######### ...
- BZOJ2006 ST表 + 堆
https://www.lydsy.com/JudgeOnline/problem.php?id=2006 题意:在长度N的序列中求K段长度在L到R之间的区间,使得他们的和最大 很容易想到要求一个前缀 ...
- 2017-12-15python全栈9期第二天第三节之作业讲解用户三次登陆
#!/user/bin/python# -*- coding:utf-8 -*-i = 0while i < 3: username = input('请输入账号:') password = i ...
- saltstack grains
saltstack的grains类似于ansible的setup模块,主要作用为手机客户端的主机基本信息(cpu,内核,os,virtual等),定义在客户端 [root@k8s_master ~]# ...
- Java测试Junit
Junit就是做测试用的,想想平常我们是怎么测试我们的方法或者类的,是不是在main方法里面去调用?这样有缺点: 1.每次都要在main方法里面写测试,假如我要上线新系统,里面有1000个方法需要测试 ...
- Java 微信公众号导出所有粉丝(openId)
由于公众号换了公司主体,需要做迁移,玩家的openId数据需要做处理. (我是按我要的json格式,将粉丝导成了1万条数据的一个json文件) 文件格式: { "info":[ { ...
- Linux记录-shell获取hdfs表查询mysql
#!/bin/sh hdfs dfs -ls /user/hive/warehouse | awk '{print $8}' | awk -F "/" '{print $5}' & ...
- Bootstrap模态框修改出现的位置和大小
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- http-request详解
HTTP请求 请求数据格式 响应数据格式 request