ZooKeeper允许用户在指定节点上注册一些Watcher,并且在一些特定事件触发的时候,ZooKeeper服务端会将事件通知到感兴趣的客户端上去,该机制是ZooKeeper实现分布式协调服务的重要特性。
ZooKeeper中引入了Watcher机制来实现了发布/订阅功能,能能够让多个订阅者同时监听某一个对象,当一个对象自身状态变化时,会通知所有订阅者。
ZooKeeper原生支持通过注册Watcher来进行事件监听,但是其使用并不是特别方便,需要开发人员自己反复注册Watcher,比较繁琐。
Curator引入了Cache来实现对ZooKeeper服务端事件的监听。
ZooKeeper提供了三种Watcher:
- NodeCache:只是监听某一个特定的节点
- PathChildrenCache:监听一个ZNode的子节点
- TreeCache:可以监控整个树上的所有节点,类似于PathChildrenCache和NodeCache的组合。
下面通过代码来监听节点情况:
1、只监听某一特定的节点(NodeCache)
public class CauratorWatchTest {
private CuratorFramework client;
@Before
public void conCli(){
RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000,10);
//建立连接
client = CuratorFrameworkFactory.builder()
.connectString("192.168.117.128:2181")
.sessionTimeoutMs(60 * 1000)
.connectionTimeoutMs(15 * 1000)
.retryPolicy(retryPolicy)
.namespace("flyrain")
.build();
client.start();
}
@After
public void clientClose(){
if(client!=null){
client .close();
}
}
/**
* ZooKeeper的watch事件监听
* NodeCache:只是监听某一个特定的节点
* PathChildrenCache:监听一个ZNode的子节点
* TreeCache:可以监控整个树上的所有节点,类似于PathChildrenCache和NodeCache的组合。
*/
@Test
public void testNodeCache(){
//1、创建NodeCache对象
NodeCache nodeCache = new NodeCache(client,"/app2");
//2、注册监听
nodeCache.getListenable().addListener(new NodeCacheListener() {
@Override
public void nodeChanged() throws Exception {
System.out.println("节点发生了变化");
//获取修改后的节点
byte[] data = nodeCache.getCurrentData().getData();
System.out.println("修改后的数据是 :"+new String(data));
}
});
//3、开启监听,设置为true,加载缓冲数据
try {
nodeCache.start(true);
//循环一直开启,模拟始终监听的状态
while (true){
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
通过SecureCRT连接的zookeeper启动客户端,./zkCli.sh,然后创建/flyrain/app2节点。
然后运行testNodeCache()方法,得到的结果如图所示:
2、监听某个节点的所有子节点
/**
* PathChildrenCache:监听某个节点的所有子节点们
*/
@Test
public void testPathChildrenCache() throws Exception {
//1.创建监听对象
PathChildrenCache pathChildrenCache = new PathChildrenCache(client,"/app2",true);
//2. 绑定监听器
pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {
@Override
public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
System.out.println("子节点变化了~");
System.out.println(event);
//监听子节点的数据变更,并且拿到变更后的数据
//1.获取类型
PathChildrenCacheEvent.Type type = event.getType();
//2.判断类型是否是update
if(type.equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)){
System.out.println("数据变了!!!");
byte[] data = event.getData().getData();
System.out.println(new String(data));
}
}
});
//3. 开启
pathChildrenCache.start();
while (true){
}
}
套路和第一个步骤是一样的,启动该方法,通过客户端进行子节点的增删改查操作,查看控制台的情况,在此就不多做介绍了。
3、监听某个节点和所有的子节点
/**
*TreeCache:监听某个节点自己和所有子节点们
*/
@Test
public void testTreeCache() throws Exception {
//1. 创建监听器
TreeCache treeCache = new TreeCache(client,"/app2");
//2. 注册监听
treeCache.getListenable().addListener(new TreeCacheListener() {
@Override
public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
System.out.println("节点变化了");
System.out.println(event);
}
});
//3. 开启
treeCache.start();
while (true){
}
}
可以根据情况,通过上述操作对节点进行监听。
路漫漫其修远兮,吾将上下而求索,希望此篇文章对大家有所帮助......