zookeeper curator使用caches实现各种监听
1、篇首语
curator是zookeeper的一个高级api开发包。封装了zookeeper众多的recipes,并且实现了一些新的recipes原语,最重要的是基于zookeeper提供的各种机制实现了更健壮的连接和异常处理。
本文将其中比较常用的一种recipe,就是cache。
2、各种Caches
cache是一种缓存机制,可以借助cache实现监听。
简单来说,cache在客户端缓存了znode的各种状态,当感知到zk集群的znode状态变化,会触发event事件,注册的监听器会处理这些事件。是不是很简单。
curator支持的cache种类有3种Path Cache,Node Cache,Tree Cache
1)Path Cache
Path Cache用来观察ZNode的子节点并缓存状态,如果ZNode的子节点被创建,更新或者删除,那么Path Cache会更新缓存,并且触发事件给注册的监听器。
Path Cache是通过PathChildrenCache类来实现的,监听器注册是通过PathChildrenCacheListener。
2)Node Cache
Node Cache用来观察ZNode自身,如果ZNode节点本身被创建,更新或者删除,那么Node Cache会更新缓存,并触发事件给注册的监听器。
Node Cache是通过NodeCache类来实现的,监听器对应的接口为NodeCacheListener。
3)Tree Cache
可以看做是上两种的合体,Tree Cache观察的是所有节点的所有数据。
3、下面给出一个例子。
1)这是在springboot中使用curator,先给出curator依赖pom
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.8</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.9.1</version>
</dependency>
2)三种cache的实现
package com.dqa.prometheus.client.zookeeper; import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.*;
import org.apache.curator.framework.recipes.cache.PathChildrenCache.StartMode;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.utils.CloseableUtils;
import org.apache.zookeeper.CreateMode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List; public class ZkClient {
private final Logger logger = LoggerFactory.getLogger(this.getClass()); private CuratorFramework client;
private NodeCache nodeCache;
private PathChildrenCache pathChildrenCache;
private TreeCache treeCache;
private String zookeeperServer;
private int sessionTimeoutMs;
private int connectionTimeoutMs;
private int baseSleepTimeMs;
private int maxRetries; public void setZookeeperServer(String zookeeperServer) {
this.zookeeperServer = zookeeperServer;
}
public String getZookeeperServer() {
return zookeeperServer;
}
public void setSessionTimeoutMs(int sessionTimeoutMs) {
this.sessionTimeoutMs = sessionTimeoutMs;
}
public int getSessionTimeoutMs() {
return sessionTimeoutMs;
}
public void setConnectionTimeoutMs(int connectionTimeoutMs) {
this.connectionTimeoutMs = connectionTimeoutMs;
}
public int getConnectionTimeoutMs() {
return connectionTimeoutMs;
}
public void setBaseSleepTimeMs(int baseSleepTimeMs) {
this.baseSleepTimeMs = baseSleepTimeMs;
}
public int getBaseSleepTimeMs() {
return baseSleepTimeMs;
}
public void setMaxRetries(int maxRetries) {
this.maxRetries = maxRetries;
}
public int getMaxRetries() {
return maxRetries;
} public void init() {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(baseSleepTimeMs, maxRetries);
client = CuratorFrameworkFactory.builder().connectString(zookeeperServer).retryPolicy(retryPolicy)
.sessionTimeoutMs(sessionTimeoutMs).connectionTimeoutMs(connectionTimeoutMs).build();
client.start();
} public void stop() {
if (client != null) CloseableUtils.closeQuietly(client);
if (pathChildrenCache != null) CloseableUtils.closeQuietly(pathChildrenCache);
if (nodeCache != null) CloseableUtils.closeQuietly(nodeCache);
if (treeCache != null) CloseableUtils.closeQuietly(treeCache);
} public CuratorFramework getClient() {
return client;
} /*
* 设置Path Cache, 监控本节点的子节点被创建,更新或者删除,注意是子节点, 子节点下的子节点不能递归监控
* 事件类型有3个, 可以根据不同的动作触发不同的动作
* 本例子只是演示, 所以只是打印了状态改变的信息, 并没有在PathChildrenCacheListener中实现复杂的逻辑
* @Param path 监控的节点路径, cacheData 是否缓存data
* 可重入监听
* */
public void setPathCacheListener(String path, boolean cacheData) {
try {
pathChildrenCache = new PathChildrenCache(client, path, cacheData);
PathChildrenCacheListener childrenCacheListener = new PathChildrenCacheListener() {
@Override
public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) {
ChildData data = event.getData();
switch (event.getType()) {
case CHILD_ADDED:
logger.info("子节点增加, path={}, data={}", data.getPath(), data.getData());
break;
case CHILD_UPDATED:
logger.info("子节点更新, path={}, data={}", data.getPath(), data.getData());
break;
case CHILD_REMOVED:
logger.info("子节点删除, path={}, data={}", data.getPath(), data.getData());
break;
default:
break;
}
}
};
pathChildrenCache.getListenable().addListener(childrenCacheListener);
pathChildrenCache.start(StartMode.POST_INITIALIZED_EVENT);
} catch (Exception e) {
logger.error("PathCache监听失败, path=", path);
} } /*
* 设置Node Cache, 监控本节点的新增,删除,更新
* 节点的update可以监控到, 如果删除会自动再次创建空节点
* 本例子只是演示, 所以只是打印了状态改变的信息, 并没有在NodeCacheListener中实现复杂的逻辑
* @Param path 监控的节点路径, dataIsCompressed 数据是否压缩
* 不可重入监听
* */
public void setNodeCacheListener(String path, boolean dataIsCompressed) {
try {
nodeCache = new NodeCache(client, path, dataIsCompressed);
NodeCacheListener nodeCacheListener = new NodeCacheListener() {
@Override
public void nodeChanged() throws Exception {
ChildData childData = nodeCache.getCurrentData();
logger.info("ZNode节点状态改变, path={}", childData.getPath());
logger.info("ZNode节点状态改变, data={}", childData.getData());
logger.info("ZNode节点状态改变, stat={}", childData.getStat());
}
};
nodeCache.getListenable().addListener(nodeCacheListener);
nodeCache.start();
} catch (Exception e) {
logger.error("创建NodeCache监听失败, path={}", path);
}
} /*
* 设置Tree Cache, 监控本节点的新增,删除,更新
* 节点的update可以监控到, 如果删除不会自动再次创建
* 本例子只是演示, 所以只是打印了状态改变的信息, 并没有在NodeCacheListener中实现复杂的逻辑
* @Param path 监控的节点路径, dataIsCompressed 数据是否压缩
* 可重入监听
* */
public void setTreeCacheListener(final String path) {
try {
treeCache = new TreeCache(client, path);
TreeCacheListener treeCacheListener = new TreeCacheListener() {
@Override
public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
ChildData data = event.getData();
if(data != null){
switch (event.getType()) {
case NODE_ADDED:
logger.info("[TreeCache]节点增加, path={}, data={}", data.getPath(), data.getData());
break;
case NODE_UPDATED:
logger.info("[TreeCache]节点更新, path={}, data={}", data.getPath(), data.getData());
break;
case NODE_REMOVED:
logger.info("[TreeCache]节点删除, path={}, data={}", data.getPath(), data.getData());
break;
default:
break;
}
}else{
logger.info("[TreeCache]节点数据为空, path={}", data.getPath());
}
}
};
treeCache.getListenable().addListener(treeCacheListener);
treeCache.start();
} catch (Exception e) {
logger.error("创建TreeCache监听失败, path={}", path);
} }
}
3)configuration
init方法是初始化zookeeper client的操作
stop是停止zookeeper是的清理动作
package com.dqa.prometheus.configuration; import com.xiaoju.dqa.prometheus.client.zookeeper.ZkClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; @Configuration
public class ZkConfiguration { @Value("${zookeeper.server}")
private String zookeeperServer;
@Value(("${zookeeper.sessionTimeoutMs}"))
private int sessionTimeoutMs;
@Value("${zookeeper.connectionTimeoutMs}")
private int connectionTimeoutMs;
@Value("${zookeeper.maxRetries}")
private int maxRetries;
@Value("${zookeeper.baseSleepTimeMs}")
private int baseSleepTimeMs; @Bean(initMethod = "init", destroyMethod = "stop")
public ZkClient zkClient() {
ZkClient zkClient = new ZkClient();
zkClient.setZookeeperServer(zookeeperServer);
zkClient.setSessionTimeoutMs(sessionTimeoutMs);
zkClient.setConnectionTimeoutMs(connectionTimeoutMs);
zkClient.setMaxRetries(maxRetries);
zkClient.setBaseSleepTimeMs(baseSleepTimeMs);
return zkClient;
} }
3)zk配置文件
其中最重要的应该是会话超时和重试机制了。
============== zookeeper ===================
zookeeper.server=10.93.21.21:,10.93.18.34:,10.93.18.35:
zookeeper.sessionTimeoutMs=
zookeeper.connectionTimeoutMs=
zookeeper.maxRetries=
zookeeper.baseSleepTimeMs=
zookeeper curator使用caches实现各种监听的更多相关文章
- ZooKeeper个人笔记之节点的监听
create public String create(String path, byte[] data, List<ACL> acl, CreateMode createMode) th ...
- ZooKeeper(3.4.5) 使用Curator监听事件
转载:http://www.mamicode.com/info-detail-494364.html 标签: ZooKeeper原生的API支持通过注册Watcher来进行事件监听,但是Watcher ...
- ZooKeeper(3.4.5) - 使用 Curator(2.7.0) 监听事件
ZooKeeper原生的API支持通过注册Watcher来进行事件监听,但是Watcher通知是一次性的,因此开发过程中需要反复注册Watcher,比较繁琐.Curator引入了Cache来监听Zoo ...
- Zookeeper Curator 事件监听 - 秒懂
目录 写在前面 1.1. Curator 事件监听 1.1.1. Watcher 标准的事件处理器 1.1.2. NodeCache 节点缓存的监听 1.1.3. PathChildrenCache ...
- 基于Zookeeper实现客户端动态监听服务器上下线
一.在具体实现之前,先来了解一下Zookeeper的监听器的原理: 图中Main()线程作为客户端,当在主线程中创建Zookeeper客户端时,会默认创建两个子线程:Listener和connect, ...
- Zookeeper开源客户端Curator之事件监听详解
Curator对Zookeeper典型场景之事件监听进行封装,提供了使用参考.这篇博文笔者带领大家了解一下Curator的实现方式. 引入依赖 对于Curator封装Zookeeper的典型场景使用都 ...
- 如何使用Curator监听zookeeper事件变化
掌握zookeeper事件监听机制,非常重要,可以说是跨入了进阶的门槛,只有掌握了如何监听某个节点或路径,我们才能在节点变化后,做一些我们想做的事,包括: 1,配置文件同步 2,主从切换 3,分布式队 ...
- 8、Curator的监听机制
原生的zookeeper的监听API所实现的方法存在一些缺点,对于开发者来说后续的开发会考虑的细节比较多. Curator所实现的方法希望摒弃原声API 的不足,是开发看起来更加的简单,一些重连等操作 ...
- Curator的监听机制
原生的zookeeper的监听API所实现的方法存在一些缺点,对于开发者来说后续的开发会考虑的细节比较多. Curator所实现的方法希望摒弃原声API 的不足,是开发看起来更加的简单,一些重连等操作 ...
随机推荐
- 九度OJ 1006 ZOJ
#include <iostream> #include <string> using namespace std; int getO(string str,int & ...
- 201521123091 《Java程序设计》第13周学习总结
Java 第十三周总结 第十三周的作业. 目录 1.本章学习总结 2.Java Q&A 3.码云上代码提交记录及PTA实验总结 4.课后阅读 1.本章学习总结 1.1 以你喜欢的方式(思维导图 ...
- 201521123076《java程序设计》第四次总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关继承的知识点. 1.2 使用常规方法总结其他上课内容. instanceof可以测试一个对象是否是某个类(或其父类),右边'is a?'左边关系. ...
- 201521123013 《Java程序设计》第13周学习总结
1. 本周学习总结 2. 书面作业 Q1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu.edu.cn,分析返回结果有何不同?为什么会有这样的不同? ping值 ...
- 201521123045 《JAVA程序设计》第1周学习总结
1. 本周学习总结 学习了入门的java知识,知道了jdk.eclipse等基础软件,了解了如何编译最基础的java程序.知道了java的基本原理以及java的几种数据类型.掌握使用简单编译器编写ja ...
- Hyperledger Fabric 1.0 从零开始(五)——运行测试e2e
3:运行测试e2e 3.1.运行fabric-samples的问题说明 该问题说明能够解决6.1.平台特定使用的二进制文件配置第一步的问题.可以选择继续阅读该说明,或者等参考到6.1小节时再反向阅读本 ...
- panda库------对数据进行操作---合并,转换,拼接
>>> frame2 addr age name 0 beijing 12 zhang 1 shanghai 24 li 2 hangzhou 24 cao >>> ...
- Maven第二篇【Idea下使用Maven】
详情可参照详细的Maven教程-Idea环境下 值得追加的是:在修改web.xml路径的时候,那篇博文并没有给出绝对的路径-这里可能有些人不知道怎么写.我给出来参考 X:\Users\ozc\Desk ...
- java基础知识2--String,StringBufffer,StringBuilder的区别
String,StringBufffer,StringBuilder的区别 1.可变不可变方面 String类中使用字符数组保存字符串 ,final 修饰当然是不可变的,用String来操作字符串的 ...
- Eclipse读取含有extjs的项目文件时卡死或者编写ExtJS时卡
新建一个Eclipse或MyEclipse项目时,关掉验证. 项目右键-->Properties-->Builders--> 不勾选(JavaScript Validator.Val ...