目录
废话不多说,直接上例子:
@Before
public void before() {
try {
CountDownLatch countDownLatch = new CountDownLatch(1);
/**
* ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)
* connectString:zookeeper主机
* sessionTimeout:会话超时时间,单位毫秒
* watcher:实现监视器对象,zookeeper通过监视器对象返回连接状态
*/
zooKeeper = new ZooKeeper("127.0.0.1:2181", 5000, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
countDownLatch.countDown();
}
System.out.println("path:"+watchedEvent.getPath());
System.out.println("evenTtype:"+watchedEvent.getType());
}
});
//主线程阻塞等待连接对象的创建成功
countDownLatch.await();
} catch (Exception e) {
e.printStackTrace();
}
}
@After
public void after() {
try {
if (zooKeeper != null) {
zooKeeper.close();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
1.exists
可以捕获到当前节点的如下变化:
- NodeCreated
- NodeDataChanged
- NodeDeleted
exists(String path, boolean watch) 布尔值为是否使用连接对象中注册的监视器
exists(String path, Watcher watcher)
1.1使用连接对象中的watcher
@Test
public void existsWatch1() throws KeeperException, InterruptedException {
zooKeeper.exists("/watch",true);
Thread.sleep(60000);
}
运行后控制台输出:
path:null
evenTtype:None
使用客户端执行:
[zk: localhost:2181(CONNECTED) 22] create /watch "123"
Created /watch
控制台变化:
path:null
evenTtype:None
path:/watch
evenTtype:NodeCreated
由于监视器是一次性的,所以我们再次运行后,控制台执行: set /watch "456"
控制台变化:
path:/watch
evenTtype:NodeDataChanged
再次运行后,控制台执行: delete /watch
控制台输出:
path:/watch
evenTtype:NodeDeleted
1.4自定义监视器实现多次监听
@Test
public void existsWatch2() throws KeeperException, InterruptedException {
Watcher watcher = new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println("自定义watcher");
System.out.println("path:" + watchedEvent.getPath());
System.out.println("evenTtype:" + watchedEvent.getType());
try {
zooKeeper.exists("/watch2", this);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
zooKeeper.exists("/watch2", watcher);
Thread.sleep(60000);
}
客户端窗口依次执行如下命令:
[zk: localhost:2181(CONNECTED) 25] create /watch2 "1"
Created /watch2
[zk: localhost:2181(CONNECTED) 26] set /watch2 "2"
cZxid = 0x118
ctime = Mon Feb 01 10:07:52 CST 2021
mZxid = 0x119
mtime = Mon Feb 01 10:08:03 CST 2021
pZxid = 0x118
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 1
numChildren = 0
[zk: localhost:2181(CONNECTED) 28] delete /watch2
[zk: localhost:2181(CONNECTED) 29] create /watch2 "1"
Created /watch2
[zk: localhost:2181(CONNECTED) 30]
控制台输出:
path:null
evenTtype:None
自定义watcher
path:/watch2
evenTtype:NodeCreated
自定义watcher
path:/watch2
evenTtype:NodeDataChanged
自定义watcher
path:/watch2
evenTtype:NodeDeleted
自定义watcher
path:/watch2
evenTtype:NodeCreated
一个节点是可以注册多个监视器的,此处就不做演示了
2. getData
可以捕获到当前节点的如下变化:
- NodeDataChanged
- NodeDeleted
getData(String path, boolean watch, Stat stat) stat为返回znode的元数据
getData(String path, Watcher watcher, Stat stat)
2.1 使用连接对象中的watcher
@Test
public void getDataWatch1() throws KeeperException, InterruptedException {
zooKeeper.getData("/watch3",true,null);
Thread.sleep(60000);
}
在启动前,我们得去客户端执行: create /watch3 "1"
然后,我们启动该方法后,执行set /watch3 "2"命令,控制台输出:
path:/watch3
evenTtype:NodeDataChanged
再次启动后执行 delete /watch3命令,控制台输出:
path:/watch3
evenTtype:NodeDeleted
2.2 自定义监视器实现多次监听
@Test
public void getDataWatch2() throws KeeperException, InterruptedException {
Watcher watcher = new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println("自定义watcher");
System.out.println("path:" + watchedEvent.getPath());
System.out.println("evenTtype:" + watchedEvent.getType());
try {
if(watchedEvent.getType()==Event.EventType.NodeDataChanged) {
zooKeeper.getData("/watch3", this, null);
}
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
zooKeeper.getData("/watch3",watcher,null);
Thread.sleep(60000);
}
在启动前,我们得去客户端执行: create /watch3 "1"
然后,我们启动该方法后,执行set /watch3 "2"命令,控制台输出:
自定义watcher
path:/watch3
evenTtype:NodeDataChanged
再次启动后执行 delete /watch3命令,控制台输出:
自定义watcher
path:/watch3
evenTtype:NodeDeleted
同样也是可以注册多个监视器的,此处就不做演示了
3.getChildren
可以捕获到如下变化:
- NodeChildrenChanged 子节点被创建出来,被删除
- NodeDeleted 当前节点被删除
getChildren(String path, boolean watch)
getChildren(String path, Watcher watcher, Stat stat)
3.1 使用连接对象中的watcher
@Test
public void getChildrenWatch1() throws KeeperException, InterruptedException {
zooKeeper.getChildren("/watch4", true);
Thread.sleep(60000);
}
在启动前,我们得去客户端执行: create /watch4 "1"
然后,我们启动该方法后,执行create /watch4/node1 "1",控制台输出:
path:/watch4
evenTtype:NodeChildrenChanged
再次启动执行 delete /watch4/node1 控制台输出:
path:/watch4
evenTtype:NodeChildrenChanged
再次启动执行 delete /watch4 控制台输出:
path:/watch4
evenTtype:NodeDeleted
3.2 自定义监视器实现多次监听
@Test
public void getChildrenWatch2() throws KeeperException, InterruptedException {
Watcher watcher = new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println("自定义watcher");
System.out.println("path:" + watchedEvent.getPath());
System.out.println("evenTtype:" + watchedEvent.getType());
try {
if(watchedEvent.getType()==Event.EventType.NodeChildrenChanged) {
zooKeeper.getChildren("/watch4", this, null);
}
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
zooKeeper.getChildren("/watch4",watcher,null);
Thread.sleep(60000);
}
这里可再次验证创建子节点,删除子节点,删除父节点 可被监视到。
同样也是可以注册多个监视器的,此处就不做演示了。