前面介绍了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. [CISCN2019 华北赛区 Day1 Web2]ikun-1

    考点:JWT身份伪造.python pickle反序列化.逻辑漏洞 1.打开之后首页界面直接看到了提示信息,信息如下: 2.那就随便注册一个账号进行登录,然后购买lv6,但是未发现lv6,那就查看下一 ...

  2. 【MySQL】DDL因Waiting for table metadata lock卡住

    在数据库空闲时间,对表做碎片整理: alter table my_abc engine=innodb; 发现会话被阻塞,显示状态是: Waiting for table metadata lock 手 ...

  3. 《Java编程思想》读书笔记(四)

    前言:三年之前就买了<Java编程思想>这本书,但是到现在为止都还没有好好看过这本书,这次希望能够坚持通读完整本书并整理好自己的读书笔记,上一篇文章是记录的第十七章到第十八章的内容,这一次 ...

  4. [第二章 web进阶]XSS闯关-1

    定义:跨站脚本(Cross_Site Scripting,简称为XSS或跨站脚本或跨站脚本攻击)是一种针对网站应用程序的安全漏洞攻击技术,是代码注入的一种.它允许恶意用户将代码注入网页,其他用户浏览网 ...

  5. KingbaseES V8R6集群维护案例之---停用集群node_export进程

    案例说明: 在KingbaseES V8R6集群启动时,会启动node_exporter进程,此进程主要用于向kmonitor监控服务输出节点状态信息.在系统安全漏洞扫描中,提示出现以下安全漏洞: 对 ...

  6. web前端小知识 —— 【HTML,CSS,JS】集锦 【第一期】 { }

    1.获取元素样式属性的方法 第 一 种 : 较灵活,能获取传进来想获取的元素的样式属性,返回的是[字符串] function getStyle(obj, name) { // IE // 主流 ret ...

  7. 利用rpmbuild 打包可执行文件和链接库生成rpm 包

    Background: Background: 遇到一个打包可执行程序和链接库生成rpm 包的需求,查遍了很多网站的资料,现在整理下解决方案. 前期参考的是这篇帖子: https://codeante ...

  8. Django 之路由层

    一.Django 请求周期生命流程图 首先,用户在浏览器中输入URL,发送一个GET 或 POST 方法的request 请求. Django 中封装了socket 的WSGI 服务器,监听端口接受这 ...

  9. Containerd 知识点

    1.查看安装Containerd的版本 # ctr --version ctr github.com/containerd/containerd v1.6.6 # ctr version Client ...

  10. 云服务器 Centos7 部署 Elasticsearch 8.0 + Kibana 8.0 指南

    文章转载自:https://mp.weixin.qq.com/s/iPfh9Mkwxf5lieiqt6ltxQ 服务器是命令行模式登录,没法以浏览器方式访问.而官方推荐的快捷部署方式,在kibana ...