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 监控得到的信息可以看出,已经成功模拟实现集群配置信息的订阅发布

相关内容

热门资讯

银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...