前面介绍了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实战之分布式统一配置获取的更多相关文章

  1. zk系列三:zookeeper实战之分布式锁实现

    一.分布式锁的通用实现思路 分布式锁的概念以及常规解决方案可以参考之前的博客:聊聊分布式锁的解决方案:今天我们先分析下分布式锁的实现思路: 首先,需要保证唯一性,即某一时点只能有一个线程访问某一资源: ...

  2. kafka系列二:多节点分布式集群搭建

    上一篇分享了单节点伪分布式集群搭建方法,本篇来分享一下多节点分布式集群搭建方法.多节点分布式集群结构如下图所示: 为了方便查阅,本篇将和上一篇一样从零开始一步一步进行集群搭建. 一.安装Jdk 具体安 ...

  3. 分布式统一配置平台-Disconf.Net

    源码地址:https://github.com/qkbao/Disconf.Net 作者:青客宝  联系qq:后续奉上 为了更好的解决分布式环境下多台服务实例的配置统一管理问题,本文提出了一套完整的分 ...

  4. ASP.NET Web API 2系列(二):灵活多样的路由配置

    1. 导言 路由系统是请求消息进入ASP.NET Web API消息处理管道的第一道屏障,其根本目的在于利用注册的路由对请求的URL进行解析以确定目标HTTPController和Action的名称, ...

  5. 【CI】系列二:Ubuntu环境虚拟机安装及配置

    好了,做好了初步计划之后,如果可行性没问题,就可以开始实践了. 准备前提:VirtualBox.ubunut镜像 如果没有,可以通过如下地址下载,安装过程此处不做描述. VirtualBox 4.3. ...

  6. Azure杂七杂八系列(二) - 如何在Azure上重新配置VM

    我们经常遇到这样的问题,  对于已经建立的VM进行性能提升, 比如需要更好的虚拟机或者需要迁移到其他的虚拟网络 那么我们可以使用以下的方法进行修改. 1. 如图所示, TESTVMXX位于North ...

  7. arcgis api 3.x for js 入门开发系列二十一气泡窗口信息动态配置模板

    前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...

  8. 【转载】网站配置Https证书系列(二):IIS服务器给网站配置Https证书

    针对网站的Https证书,即SSL证书,腾讯云.阿里云都提供了免费的SSL证书申请,SSL证书申请下来后,就需要将SSL证书配置到网站中,如果网站使用的Web服务器是IIS服务器,则需要在IIS服务器 ...

  9. JBOSS EAP 6 系列五 Managed domains 管理域最主要的功能是“统一部署,统一配置”

    摘要 本文首先介绍Managed Domain的概念,管理域最主要的功能是"统一部署,统一配置".接下来通过一个实例在"统一配置"部分实现一个双机配置起来的域, ...

随机推荐

  1. 校园网跨网段共享文件Samba+SSH

    Introduction This tutorial contains screenshots for the English version of Windows 10. Separate inst ...

  2. 在hyper-v虚拟机中安装并配置linux

    虽然都是自己写的,还是贴个原文链接吧,如果文章里的图片错乱了,可能就是我贴错了,去看原文吧. 多图警告 WSL2真香? WSL2相比于WSL1前者更类似于虚拟机,配合上Windoes Terminal ...

  3. 累加和为 K 的最长子数组问题

    累加和为 K 的最长子数组问题 作者:Grey 原文地址: 博客园:累加和为 K 的最长子数组问题 CSDN:累加和为 K 的最长子数组问题 题目描述 给定一个整数组成的无序数组 arr,值可能正.可 ...

  4. Latex中也能展示动态图?

    技术背景 在学术领域,很多文档是用Latex做的,甚至有很多人用Latex Beamer来做PPT演示文稿.虽然在易用性和美观等角度来说,Latex Beamer很大程度上不如PowerPoint,但 ...

  5. Beats:使用Elastic Stack对Redis监控

  6. MySQL集群搭建(5)-MHA高可用架构

    1 概述 1.1 MHA 简介 MHA - Master High Availability 是由 Perl 实现的一款高可用程序,出现故障时,MHA 以最小的停机时间(通常10-30秒)执行 mas ...

  7. 为什么 CRM 能帮助装备制造企业进行数字化转型?

    CRM确实能帮助装备制造企业进行数字化转型,体现在销售管理端,能方便的服务于"客户需求"为主旨的数字化转型思想,用客户的需求来指导生产等.但这个说法有点片面,毕竟那只是客户管理部分 ...

  8. Jupyter Notebook单元格加宽的方法3种

    Jupyter Notebook的代码单元格比较窄,在我的屏幕上只占了一半都不到,网络搜索下,共找到3种加宽的方法,总结一下. (一)只改变当前Jupyter笔记本的单元格宽度 在Jupyter No ...

  9. [笔记] CSP 初赛 部分知识整理

    几年前整理的东西,要不就发到网上吧 不过现在这些东西里面也有很多考得比以前少了 卡特兰数 \(f(i)=\sum_\limits{i=0}^{n-1}{f(i)f(n-i-1)}\) 其中\(f(0) ...

  10. display:block 和display:inline-block的区别和用法

    1).块状元素:(div,p,form,ul,ol,li) ,独占一行,默认情况width为100% 2).行内块状元素:(span,img,a),不会独占一行,相邻的元素一直排在同一行,排满了才会换 ...