zk系列二:zookeeper实战之分布式统一配置获取
前面介绍了zk的一些基础知识,这篇文章主要介绍下如何在java环境下获取zk的配置信息;主要基于zk的监听器以及回调函数通过响应式编程的思想将核心代码糅合成一个工具类,几乎做到了拿来即用;
在分布式集群中,配置信息一般都会拎出来单独配置,这样避免了修改配置信息时候的复杂度,我们期望当有配置变更时集群中的节点能及时得到通知并作出响应;我们可以在每个节点中开启任务定时来zk获取信息,然后根据获取信息的前后是否有差异来判断信息是否变更,但是这种方法明显不及时,且每次轮询zk都会增加不必要的网络开销,特别是节点众多时给ZK增加了不必要的压力;所以我们更倾向于利用ZK的监听和回调机制来实现类似的统一消息配置,客户端只要注册一个监听器当节点信息发生变更时zk会主动触发对应事件,客户端监听对应事件作出响应即可;下面先贴出代码流程图,然后再贴出关键代码
代码执行流程:

关键代码如下:
1、测试类
package com.darling.service.zookeeper;
import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.ZooKeeper;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* @description: 使用响应式编程思想实现基于ZK的分布式统一配置功能
* @author: dll
* @date: Created in 2022/11/1 12:21
* @version:
* @modified By:
*/
@Slf4j
public class ZkConfigTest {
ZooKeeper zkClient;
@Before
public void conn (){
zkClient = ZkUtil.getZkClient();
}
@After
public void close (){
try {
zkClient.close();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Test
public void test() throws InterruptedException {
ConfigData configData = new ConfigData();
ZkConfigUtil watchAndCallBack = new ZkConfigUtil();
watchAndCallBack.setZkClient(zkClient);
watchAndCallBack.setConfigData(configData);
watchAndCallBack.await();
String config = configData.getConfig();
while(true){
if(configData.getConfig().equals("")){
System.out.println("配置信息丢失 ......");
watchAndCallBack.await();
}else{
System.out.println(configData.getConfig());
}
// 此处睡眠的原因是为了便于日志打印
try {
Thread.sleep(600);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
2、关键工具类
package com.darling.service.zookeeper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.AsyncCallback;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import java.util.concurrent.CountDownLatch;
/**
* @description:
* @author: dll
* @date: Created in 2022/11/1 12:40
* @version:
* @modified By:
*/
@Data
@Slf4j
public class ZkConfigUtil implements Watcher, AsyncCallback.StatCallback, AsyncCallback.DataCallback {
ZooKeeper zkClient;
ConfigData configData;
CountDownLatch cc = new CountDownLatch(1);
private final String nodePath = "/config";
/**
* 异步获取数据getData方法的回调
* @param rc 状态码
* @param path 路径
* @param ctx 上线文
* @param data 节点的数据
* @param stat 元数据信息
*/
@Override
public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {
if (data != null ){
configData.setConfig(new String(data));
cc.countDown();
}
}
/**
* exists方法的回调,当数据存在时会调回调函数
* @param rc 状态码
* @param path 路径
* @param ctx 上下文
* @param stat 元数据信息,可通过其是否为空判断是否有数据
*/
@Override
public void processResult(int rc, String path, Object ctx, Stat stat) {
log.info("进入exists方法的回调,stat:{}");
if (stat != null) {
log.info("进入exists方法的回调,stat 不为空");
// 表示path节点有数据了,可以通过getData获取
zkClient.getData(nodePath, this, this,"123");
}
}
/**
* 节点变更的监听器
* @param event
*/
@Override
public void process(WatchedEvent event) {
switch (event.getType()) {
case None:
break;
case NodeCreated:
log.info("节点被创建,path:{}",event.getPath());
// 节点创建后获取一遍数据还有个额外的不可忽略的作用:即重新注册了watch,否则根据zk的watch只生效一次的规则,不会再次出发watch
zkClient.getData(nodePath, this, this,"123");
break;
case NodeDeleted:
log.info("节点被删除,path:{}",event.getPath());
configData.setConfig("");
cc = new CountDownLatch(1);
break;
case NodeDataChanged:
log.info("节点被修改,path:{}",event.getPath());
// 节点修改获取数据的作用同节点创建
zkClient.getData(nodePath, this, this,"123");
break;
case NodeChildrenChanged:
break;
}
}
public void await() {
/**
* 直接获取配置前先判断配置存不存在
* 第一个参数path:配置存放的节点路径
* 第二个参数watch:path的监听,当path有变动时回调通知
* 第三个参数StatCallback:如果path下有数据会回调此方法,可以通过Stat是否为空判断path是否有数据
*/
zkClient.exists(nodePath, this,this ,"PPP");
try {
cc.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
zk系列二:zookeeper实战之分布式统一配置获取的更多相关文章
- zk系列三:zookeeper实战之分布式锁实现
一.分布式锁的通用实现思路 分布式锁的概念以及常规解决方案可以参考之前的博客:聊聊分布式锁的解决方案:今天我们先分析下分布式锁的实现思路: 首先,需要保证唯一性,即某一时点只能有一个线程访问某一资源: ...
- kafka系列二:多节点分布式集群搭建
上一篇分享了单节点伪分布式集群搭建方法,本篇来分享一下多节点分布式集群搭建方法.多节点分布式集群结构如下图所示: 为了方便查阅,本篇将和上一篇一样从零开始一步一步进行集群搭建. 一.安装Jdk 具体安 ...
- 分布式统一配置平台-Disconf.Net
源码地址:https://github.com/qkbao/Disconf.Net 作者:青客宝 联系qq:后续奉上 为了更好的解决分布式环境下多台服务实例的配置统一管理问题,本文提出了一套完整的分 ...
- ASP.NET Web API 2系列(二):灵活多样的路由配置
1. 导言 路由系统是请求消息进入ASP.NET Web API消息处理管道的第一道屏障,其根本目的在于利用注册的路由对请求的URL进行解析以确定目标HTTPController和Action的名称, ...
- 【CI】系列二:Ubuntu环境虚拟机安装及配置
好了,做好了初步计划之后,如果可行性没问题,就可以开始实践了. 准备前提:VirtualBox.ubunut镜像 如果没有,可以通过如下地址下载,安装过程此处不做描述. VirtualBox 4.3. ...
- Azure杂七杂八系列(二) - 如何在Azure上重新配置VM
我们经常遇到这样的问题, 对于已经建立的VM进行性能提升, 比如需要更好的虚拟机或者需要迁移到其他的虚拟网络 那么我们可以使用以下的方法进行修改. 1. 如图所示, TESTVMXX位于North ...
- arcgis api 3.x for js 入门开发系列二十一气泡窗口信息动态配置模板
前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...
- 【转载】网站配置Https证书系列(二):IIS服务器给网站配置Https证书
针对网站的Https证书,即SSL证书,腾讯云.阿里云都提供了免费的SSL证书申请,SSL证书申请下来后,就需要将SSL证书配置到网站中,如果网站使用的Web服务器是IIS服务器,则需要在IIS服务器 ...
- JBOSS EAP 6 系列五 Managed domains 管理域最主要的功能是“统一部署,统一配置”
摘要 本文首先介绍Managed Domain的概念,管理域最主要的功能是"统一部署,统一配置".接下来通过一个实例在"统一配置"部分实现一个双机配置起来的域, ...
随机推荐
- 移动/联通APN提升
绝大部分的时候信号满格速度特别慢 解决办法不一定对所有人有效可尝试一下 一般流程手机的设置-移动网络-移动数据-接入点名称(APN)-新建APN 中国移动如下配置 名称:随便写 APN:cmtds m ...
- K8S服务滚动升级
对于Kubernetes集群来说,一个service可能有多个pod,滚动升级(Rolling update)就是指每次更新部分Pod,而不是在同一时刻将该Service下面的所有Pod shutdo ...
- Docker安装Redis并使用Another Redis Desktop Manager连接
Redis简单介绍 Redis全称是Remote DIctionary Service,即远程字典服务.Redis 是一个使用C语言编写的.开源的(遵守 BSD 协议).高性能的.支持网络.可基于内存 ...
- zabbix客户端无法上传数据
昨天发现有一台Windows服务器无法向zabbix服务端汇报数据.经过检查Windows上的客户端日志,可以看到以下错误. 31976:20200206:154445.873 active chec ...
- Elasticsearch6.2服务器升配后的bug
.suofang img { max-width: 100% !important; height: auto !important } 本篇文章记录最近一次生产服务器硬件升级之后引起集群不稳定的现象 ...
- Logstash: 启动监控及集中管理
在本篇文章里,我将详细介绍如果启动Logstash的监控及集中管理. 前提条件 安装好Logstash,设置Elasticsearch及Kibana的安全密码. 如何监控Logstash? 我们安装如 ...
- Elasticsearch不支持事务有什么好的弥补方案
1.问题 源自星球同学的提问:es如何与hive或mysql结合使用?es不支持事务有什么好的弥补方案吗? 2.事务的核心概念 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下ACID四个 ...
- MySQL集群搭建(3)-MMM高可用架构
1 MMM 介绍 1.1 简介 MMM 是一套支持双主故障切换以及双主日常管理的第三方软件.MMM 由 Perl 开发,用来管理和监控双主复制,虽然是双主架构,但是业务上同一时间只允许一个节点进行写入 ...
- Pod的dns记录怎么组成的
Pod的dns记录怎么组成的 <Pod Name>.<service name>.<namespace name>.svc.cluster.local Pod的Na ...
- 初试Jenkins2.0 Pipeline持续集成
转载自:https://cloud.tencent.com/developer/article/1010628 1.Jenkins 2.0介绍 先介绍下什么是Jenkins 2.0,Jenkins 2 ...