ZooKeeper在实际开发中的应用-事件监听
事件监听
Apache Curator是Netflix公司开源的一个Zookeeper客户端,与Zookeeper提供的原生客户端相比,Curator的抽象层次更高,简化了Zookeeper客户端的开发量。Patrixck Hunt(Zookeeper committer)以一句 Guava is to Java what Curator is to Zookeeper 给予高度评价。
Watcher 标准事件处理器
Watcher watcher = new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
log.info("监听到的变化 watchedEvent = " + watchedEvent);
}
};
byte[] content = curatorFramework.getData()
.usingWatcher(watcher).forPath('/path');
log.info("监听节点内容:" + new String(content));
// 变更节点数据
curatorFramework.setData().forPath(workerPath, "Change".getBytes());
Thread.sleep(Integer.MAX_VALUE);
Watcher监听器是一次性的,可以在事件触发之后重复订阅
Watcher watcher = null;
watcher = new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
curatorFramework.getData()
.usingWatcher(watcher).forPath('/path')
log.info("监听到的变化 watchedEvent = " + watchedEvent);
}
};
Curator引入Cache实现监听
Curator引入了Cache来方便我们订阅事件。
- NodeCache 监控本节点的新增,删除,更新
- PathChildrenCache 不会对二级子节点进行监听,只会对子节点进行监听
- TreeCache 监听指定节点下所有节点的变化
我这里用NodeCache
举例子
NodeCache nodeCache =
new NodeCache(curatorFramework, workerPath);
nodeCache.start();
NodeCacheListener listener = new NodeCacheListener() {
@Override
public void nodeChanged() throws Exception {
ChildData childData = nodeCache.getCurrentData();
log.info("ZNode Change, data={}", new String(childData.getData(), "Utf-8"));
}
};
nodeCache.getListenable().addListener(listener);
// 变更节点数据
curatorFramework.setData().forPath(workerPath, "Change1".getBytes());
Thread.sleep(1000L)
curatorFramework.setData().forPath(workerPath, "Change2".getBytes());
Thread.sleep(1000L)
curatorFramework.setData().forPath(workerPath, "Change3".getBytes());
Thread.sleep(10_000L);
使用场景
我们项目使用微服务技术对原有服务进行拆分,将接口分散到不同服务中,并将网关独立出来。服务端一部分接口需要登录才可以访问,网关需要对这部分接口和TOKEN进行校验。但是我们对需登录的接口的标记是基于注解的,方便切面拦截。拆分服务后网关是不知道哪些接口是需要校验的,最后我们借助了ZK来实现,下游服务发布时扫描代码中的接口,将需要登录的接口set到ZK中,网关启动时从ZK节点中取数据保存到内存中并订阅该节点,每次下游服务发布时触发事件,更新网关中的数据。
下游服务实现
网关实现
参考文档
ZooKeeper在实际开发中的应用-事件监听
https://blog.yjll.blog/post/bf85b35c.html