ZooKeeper学习笔记三:使用ZooKeeper实现一个简单的配置中心
作者:Grey
原文地址:ZooKeeper学习笔记三:使用ZooKeeper实现一个简单的配置中心
前置知识
完成ZooKeeper集群搭建以及熟悉ZooKeeperAPI基本使用
需求
很多程序往往是通过心跳检测来判断配置的变更,通过zk的回调机制,我们可以实现比心跳更为快速的配置检测机制,包括配置的新增,修改和删除
流程也比较简单:

环境准备
一个zk集权,ip和端口分别为:
- 192.168.205.145:2181
- 192.168.205.146:2181
- 192.168.205.147:2181
- 192.168.205.148:2181
定义主方法
App.java
public class App {
public static void main(String[] args) {
// 需要监控的路径是/AppConf
String path = "/AppConf";
while (true) {
ConfigCenter configCenter = new ConfigCenter(path);
String conf = configCenter.getConf();
// 配置不为空则拿到最新的配置
if (null != conf && !conf.trim().isEmpty()) {
System.out.println(conf);
}
// 睡眠一段时间
pending(1000);
}
}
}
zk初始化工具类
参考ZooKeeperAPI基本使用中的ZookeeperConfig类,主要的方法为:
public class ZookeeperConfig {
private static final String ADDRESS = "192.168.205.145:2181,192.168.205.146:2181,192.168.205.147:2181,192.168.205.148:2181";
private static ZooKeeper zk;
static CountDownLatch latch;
// 获取一个zk客户端
public static ZooKeeper create() {
latch = new CountDownLatch(1);
try {
zk = new ZooKeeper(ADDRESS, 3000, new DefaultWatch());
latch.await();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return zk;
}
...
}
实现配置中心逻辑
配置中心的入口方法为:getConf()
public String getConf() {
aWait();
return value;
}
其中aWait()方法用于监听配置信息的变动(比如修改,删除,增加),并且通过CountDownLatch阻塞运行,zk一旦监听到配置信息的变动,即会触发回调,并执行countDown(),这样前面的CountDownLatch即可往下运行:
public void aWait() {
zk.exists(conf, this, this, "dasdfa");
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
ConfigCenter类实现了Watcher, AsyncCallback.StatCallback, AsyncCallback.DataCallback三个接口,所以监听方法和回调方法都在ConfigCenter中实现,其中,监听方法:
@Override
public void process(WatchedEvent event) {
Event.EventType type = event.getType();
switch (type) {
case None:
break;
case NodeCreated:
System.out.println("node created");
zk.getData(conf, this, this, "node created");
latch.countDown();
break;
case NodeDeleted:
try {
System.out.println("config deleted");
this.value = "";
latch = new CountDownLatch(1);
} catch (Exception e) {
e.printStackTrace();
}
break;
case NodeDataChanged:
System.out.println("node changed");
zk.getData(conf, this, this, "node changed");
latch.countDown();
break;
case NodeChildrenChanged:
break;
case DataWatchRemoved:
break;
case ChildWatchRemoved:
break;
case PersistentWatchRemoved:
break;
}
}
如上,当监听到节点创建和修改的时候,触发getData,当监听到节点删除的时候,重新初始化CountDownLatch,让线程阻塞。
回调方法如下:
@Override
public void processResult(int rc, String path, Object ctx, Stat stat) {
if (stat != null) {
zk.getData(conf, this, this, "getData");
}
}
@Override
public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {
if (data != null) {
this.value = new String(data);
latch.countDown();
}
}
方法1表示,当节点存在(stat!=null)的时候,获取一次数据(重新注册监听)。
方法2表示,当节点数据存在的时候,将节点数据取出,并且countDown(),解除阻塞。
运行效果
先把zk中的/AppConf节点删除,执行App.java,程序阻塞
通过zkCli.sh连接任意zk服务端,创建一个/AppConf节点,并赋值
[zk: localhost:2181(CONNECTED) 58] create /AppConf "hello"
Created /AppConf
控制台同时打印出:
node created
hello
hello
hello
hello
hello
hello
hello
hello
继续通过zkCli重新设置/AppConf节点的值
[zk: localhost:2181(CONNECTED) 59] set /AppConf "world"
[zk: localhost:2181(CONNECTED) 60]
配置信息立马生效,控制台打印
...
hello
hello
node changed
world
world
world
...
通过zkCli.sh删除/AppConf节点,控制台阻塞运行,并打印
config deleted
通过zkCli.sh重新创建/AppConf节点,
[zk: localhost:2181(CONNECTED) 61] create /AppConf "hello2"
Created /AppConf
控制台立即解除阻塞,并打印
config deleted
node created
hello2
hello2
..
完整代码
ZooKeeper学习笔记三:使用ZooKeeper实现一个简单的配置中心的更多相关文章
- angular学习笔记(三十)-指令(9)-一个简单的指令示例
学了前面这么多关于指令的知识,现在就用指令来写一个小组件:expander 这个组件的功能就是点击开展菜单,再点击收起菜单: ↑↓点击展开收起 下面来看它的代码: html: <!DOCTYPE ...
- QML学习笔记(五)— 做一个简单的待做事项列表
做一个简单的QML待做事项列表,能够动态添加和删除和编辑数据 GitHub:八至 作者:狐狸家的鱼 本文链接:QML学习笔记(五)— 做一个待做事项列表 主要用到QML:ListView 效果 全部代 ...
- ROS学习笔记三:编写第一个ROS节点程序
在编写第一个ROS节点程序之前需要创建工作空间(workspace)和功能包(package). 1 创建工作空间(workspace) 创建一个catkin_ws: #注意:如果使用sudo一次 ...
- Directx11学习笔记【十三】 实现一个简单地形
本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5510294.html 上一个教程我们实现了渲染一个会旋转的立方体, ...
- Directx11学习笔记【四】 封装一个简单的Dx11DemoBase
根据前面两个笔记的内容,我们来封装一个简单的基类,方便以后的使用. 代码和前面类似,没有什么新的内容,直接看代码吧(由于代码上次都注释了,这次代码就没怎么写注释o(╯□╰)o) Dx11DemoBas ...
- 【WPF】学习笔记(一)——做一个简单的电子签名板
参加实习(WPF)已经有两个多周的时间了,踩了一些坑,也算积累了一些小东西,准备慢慢拿出来分享一下.(●'◡'●) 这次呢就讲讲一个简单的电子签名板的实现. 先上张图(PS:字写得比较丑,不要太在意哈 ...
- Directx11学习笔记【十一】 画一个简单的三角形--effect框架的使用
这里不再介绍effect框架的具体使用,有关effect框架使用可参考http://www.cnblogs.com/zhangbaochong/p/5475961.html 实现的功能依然是画一个简单 ...
- SpringCloud学习笔记(九):SpringCloud Config 分布式配置中心
概述 分布式系统面临的-配置问题 微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务.由于每个服务都需要必要的配置信息才能运行,所以一套集中式的.动 ...
- Directx11学习笔记【十】 画一个简单的三角形
本篇笔记要实现的是在屏幕上渲染出一个三角形,重点要学习的是渲染一个几何体的流程方式. 为了渲染几何图形,需要一个顶点缓存和一个描述顶点布局的输入层,还有着色器(主要是顶点着色器和像素着色器),下面来看 ...
随机推荐
- C/C++ 实现多线程与线程同步
多线程中的线程同步可以使用,CreateThread,CreateMutex 互斥锁实现线程同步,通过临界区实现线程同步,Semaphore 基于信号实现线程同步,CreateEvent 事件对象的同 ...
- 路由器逆向分析------MIPS系统网络的配置(QEMU)
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/69378333 MIPS系统网络的配置 使用QEMU 模拟正在运行的MIPS系统并 ...
- Win64 驱动内核编程-34.对抗与枚举MiniFilter
对抗与枚举MiniFilter MiniFilter 是目前杀毒软件用来实现"文件系统自我保护"和"文件实时监控"的方法. 由于 MiniFilter 模型简单 ...
- 【Linux】在centos中使用命令安装redis
1.前提centos能够上网 测试方式输入命令,有数据返回即可.如果则先配置centos网络连接. ping www.baidu.com 2.安装gcc 输入命令进行安装 yum install gc ...
- SecureCRT 基本设置
1:字体与大小 Lucida Console 四号 2:声音关闭 Terminal-->Audio bell不勾选 默认网络工程师常用: Terminal-->Emulation--& ...
- 在微信框架模块中,基于Vue&Element前端,通过动态构建投票选项,实现单选、复选的投票操作
最近把微信框架的前端改造一下,在原来基于Bootstrap框架基础上的微信后台管理,增加一套Vue&Element的前端,毕竟Vue的双向绑定开发起来也还是很方便的,而且Element本身也提 ...
- 微服务架构开发电商系统需要用Redis、ES和MQ吗?
如果不用什么很高大上的东西,就是有多个微服务就行这种技术架构会很难吗? 我看了一些视频,他们都用到了es.mq.redis的东西,我想不用这些东西,就简单的有多个服务,这样可行吗? 01 使用微服务你 ...
- [源码解析] 并行分布式框架 Celery 之 Lamport 逻辑时钟 & Mingle
[源码解析] 并行分布式框架 Celery 之 Lamport 逻辑时钟 & Mingle 目录 [源码解析] 并行分布式框架 Celery 之 Lamport 逻辑时钟 & Ming ...
- LeetCode 617. 合并二叉树 Java
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠. 你需要将他们合并为一个新的二叉树.合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 ...
- [刷题] 435 Non-overlapping Intervals
要求 贪心算法与动态规划的关系 给定一组区间,最少删除多少个区间,可以让这些区间之间互相不重叠 给定区间的起始点永远小于终止点 示例 [[1,2],[2,3],[3,4],[1,3]], 返回1 [[ ...