Zookeeper:实现“通知协调”的 Demo
创始人
2024-04-11 04:05:55
0

应用配置集中到节点上,应用启动时主动获取,并在节点上注册一个 watcher,每次配置更新都会通知到应用。数据发布/订阅(Publish/Subscribe)系统,即所谓的配置中心,顾名思义就是发布者将数据发布到 ZooKeeper 的一个或一系列节点上,供订阅者进行数据订阅,进而达到动态获取数据的目的,实现配置信息的集中式管理和数据的动态更新。

本篇内容包括:Demo 概述、代码实现、测试结果


文章目录

    • 一、Demo 概述
        • 1、关于 zookeeper “通知协调”
        • 2、Demo 设计
        • 3、Demo 前提
    • 二、代码实现
        • 1、引用 Maven 依赖
        • 2、ConnectionWatcher 类创建 Zookeeper 连接
        • 3、ActiveKeyValueStore 类读写 Zookeeper 数据
        • 4、ConfigUpdater 类发布数据信息
        • 5、ConfigWatcher 类订阅数据信息
    • 三、测试结果
        • 1、ConfigUpdater 打印内容
        • 2、ConfigWatcher 打印内容


一、Demo 概述

1、关于 zookeeper “通知协调”

应用配置集中到节点上,应用启动时主动获取,并在节点上注册一个 watcher,每次配置更新都会通知到应用。

数据发布/订阅(Publish/Subscribe)系统,即所谓的配置中心,顾名思义就是发布者将数据发布到 ZooKeeper 的一个或一系列节点上,供订阅者进行数据订阅,进而达到动态获取数据的目的,实现配置信息的集中式管理和数据的动态更新。

2、Demo 设计

采用发布/订阅模式将配置信息发布到 Zookeeper 节点上,供订阅者动态获取数据:

Zookeeper订阅发布Demo
  1. 首先需要启动 Zookeeper 服务,规划集群配置信息存放的节点 /config;
  2. 然后通过 ConfigWatcher 类更新 /config 节点注册监视器 watcher,监控集群配置信息变化;
  3. 最后通过 ConfigUpdater 类不断更新 /config 节点配置信息,从而模拟实现集群配置信息订阅发布效果。

3、Demo 前提

参考:Mac通过Docker安装Zookeeper集群


二、代码实现

1、引用 Maven 依赖

        org.apache.zookeeperzookeeper3.7.0

2、ConnectionWatcher 类创建 Zookeeper 连接

import java.io.IOException;
import java.util.concurrent.CountDownLatch;import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;public class ConnectionWatcher implements Watcher {private final CountDownLatch connectedSignal = new CountDownLatch(1);private static final int SESSION_TIMEOUT = 5000;protected ZooKeeper zk;public void connect(String hosts) throws IOException, InterruptedException {zk = new ZooKeeper(hosts, SESSION_TIMEOUT, this);connectedSignal.await();}@Overridepublic void process(WatchedEvent event) {if (event.getState() == Event.KeeperState.SyncConnected) {connectedSignal.countDown();}}public void close() throws InterruptedException {zk.close();}}

3、ActiveKeyValueStore 类读写 Zookeeper 数据

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.data.Stat;public class ActiveKeyValueStore extends ConnectionWatcher {private static final Charset CHARSET = StandardCharsets.UTF_8;/*** 读取节点数据** @param path  节点地址* @param value 数据值* @throws InterruptedException 中断异常* @throws KeeperException ZooKeeper异常*/public void write(String path, String value) throws InterruptedException, KeeperException {Stat stat = zk.exists(path, false);if (stat == null) {if (value == null) {zk.create(path, null,ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);} else {zk.create(path, value.getBytes(CHARSET),ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);}} else {if (value == null) {zk.setData(path, null, -1);} else {zk.setData(path, value.getBytes(CHARSET), -1);}}}/*** 读取节点数据** @param path 节点地址* @param watcher watcher* @return 数据值* @throws InterruptedException 中断异常* @throws KeeperException ZooKeeper异常*/public String read(String path, Watcher watcher) throws InterruptedException, KeeperException {/* stat */byte[] data = zk.getData(path, watcher, null);return new String(data, CHARSET);}
}

4、ConfigUpdater 类发布数据信息

import java.io.IOException;
import java.util.Random;
import java.util.concurrent.TimeUnit;import org.apache.zookeeper.KeeperException;public class ConfigUpdater {public static final String PATH = "/configuration";private final ActiveKeyValueStore store;private final Random random = new Random();public ConfigUpdater(String hosts) throws IOException, InterruptedException {//定义一个类store = new ActiveKeyValueStore();//连接Zookeeperstore.connect(hosts);}public void run() throws InterruptedException, KeeperException {// noinspection InfiniteLoopStatementwhile (true) {String value = random.nextInt(100) + "";//向 ZNode 写数据(也可以将xml文件写进去)store.write(PATH, value);System.out.printf("Set %s to %s\n", PATH, value);TimeUnit.SECONDS.sleep(random.nextInt(10));}}public static void main(String[] args) throws IOException, InterruptedException, KeeperException {String hosts = "localhost:2181";ConfigUpdater updater = new ConfigUpdater(hosts);updater.run();}
}

5、ConfigWatcher 类订阅数据信息

import java.io.IOException;import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;public class ConfigWatcher implements Watcher {private final ActiveKeyValueStore store;public ConfigWatcher(String hosts) throws InterruptedException, IOException {store = new ActiveKeyValueStore();//连接Zookeeperstore.connect(hosts);}public void displayConfig() throws InterruptedException, KeeperException {String value = store.read(ConfigUpdater.PATH, this);System.out.printf("Read %s as %s\n", ConfigUpdater.PATH, value);}@Overridepublic void process(WatchedEvent event) {System.out.printf("Process incoming event: %s\n", event.toString());if (event.getType() == Event.EventType.NodeDataChanged) {try {displayConfig();} catch (InterruptedException e) {System.err.println("Interrupted. Exiting");Thread.currentThread().interrupt();} catch (KeeperException e) {System.err.printf("KeeperException: %s. Exiting.\n", e);}}}public static void main(String[] args) throws IOException, InterruptedException, KeeperException {String hosts = "localhost:2181";//创建 watcherConfigWatcher watcher = new ConfigWatcher(hosts);//调用 display 方法watcher.displayConfig();//然后一直处于监控状态Thread.sleep(Long.MAX_VALUE);}
}

三、测试结果

1、ConfigUpdater 打印内容

Set /configuration to 76
Set /configuration to 55
Set /configuration to 13
...

2、ConfigWatcher 打印内容

Read /configuration as 76
Read /configuration as 55
Read /configuration as 13
...

通过 ConfigUpdater 发布的信息以及 ConfigWatcher 监控得到的信息可以看出,已经成功模拟实现集群配置信息的订阅发布

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...