zoukankan      html  css  js  c++  java
  • 基于Zookeeper实现配置中心

    在Zookeeper的主要应用场景中,其中之一是作为分布式系统的配置中心。

    实现原理
    在Zookeeper建立一个根节点,比如/CONFIG,代表某个配置文件。将配置文件中的信息作为根节点的子节点存储,比如配置项timeout=3000,在Zookeeper中展现为:/CONFIG/timeout ,节点内容是3000。然后让所有使用到该配置信息的应用机器集成Zookeeper并监控/CONFIG的状态,一旦配置信息也就是子节点发生变化,每台应用机器就会收到ZK的通知,然后从ZK中获取新的配置信息应用到系统中。

    以下代码仅用于展现实现思路,具体生产还需要根据实际场景处理和优化
    我们使用Curator来实现一个简易的配置中心,关于Curator框架的使用可参考zookeeper客户端框架Curator

    项目中引入依赖包:

    <dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>4.0.1</version>
    </dependency>
    <dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-client</artifactId>
    <version>4.0.1</version>
    </dependency>


    Config.java 配置类

    public class Config {
    private Map<String, String> cache = new HashMap<>();
    private CuratorFramework client;
    private static final String CONFIG_PREFIX = "/CONFIG";

    // 初始化zk连接
    public Config() {
    this.client = CuratorFrameworkFactory.newClient("localhost:2181", new RetryNTimes(3, 1000));
    this.client.start();
    this.init();
    }

    public void init() {
    try {
    // 从zk中获取配置项并保存到缓存中
    List<String> childrenNames = client.getChildren().forPath(CONFIG_PREFIX);
    for (String name : childrenNames) {
    String value = new String(client.getData().forPath(CONFIG_PREFIX + "/" + name));
    cache.put(name, value);
    }

    // 绑定一个监听器 cacheData设为true,事件发生后可以拿到节点发送的内容。
    // 使用该配置文件的每个应用机器都需要监听,这里只是用于演示
    PathChildrenCache watcher = new PathChildrenCache(client, CONFIG_PREFIX, true);
    watcher.getListenable().addListener(new PathChildrenCacheListener() {
    @Override
    public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent event) throws Exception {

    String path = event.getData().getPath();
    if (path.startsWith(CONFIG_PREFIX)) {
    String key = path.replace(CONFIG_PREFIX + "/", "");
    // 子节点新增或变更时 更新缓存信息
    if (PathChildrenCacheEvent.Type.CHILD_ADDED.equals(event.getType()) ||
    PathChildrenCacheEvent.Type.CHILD_UPDATED.equals(event.getType())) {
    cache.put(key, new String(event.getData().getData()));
    }
    // 子节点被删除时 从缓存中删除
    if (PathChildrenCacheEvent.Type.CHILD_REMOVED.equals(event.getType())) {
    cache.remove(key);
    }
    }
    }
    });
    watcher.start();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    // 保存配置信息
    public void save(String name, String value) {
    String configFullName = CONFIG_PREFIX + "/" + name;
    try {
    Stat stat = client.checkExists().forPath(configFullName);
    if (stat == null) {
    client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath(configFullName, value.getBytes());
    } else {
    client.setData().forPath(configFullName, value.getBytes());
    }
    cache.put(name, value);
    } catch (Exception e) {
    e.printStackTrace();
    }

    }
    // 获取配置信息
    public String get(String name) {
    return cache.get(name);
    }
    }

    Test.java 测试类

    public class Main {
    public static void main(String[] args) {
    Config config = new Config();
    // 模拟一个配置项,实际生产中会在系统初始化时从配置文件中加载进来
    config.save("timeout", "1000");

    // 每3S打印一次获取到的配置项
    for (int i = 0; i < 10; i++) {
    System.out.println(config.get("timeout"));
    try {
    Thread.sleep(3000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }


    启动本地zookeeper服务器,我们来测试下。Main.java执行后会在控制台每隔3S打印一下当前获取到的配置信息,当我们使用其它zk客户端重新设置timeout值时会发现获取到的信息及时更新了。


    至此,我们使用Zookeeper实现了一个简单的共享配置中心。
    ————————————————
    版权声明:本文为CSDN博主「岸远水声微」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/hzygcs/article/details/88387408

  • 相关阅读:
    基于Yarp的http内网穿透库HttpMouse
    Redis+Lua解决高并发场景抢购秒杀问题
    SQL慢查询排查思路
    webrtc之TURE、STUN、摄像头打开实战
    WebService就该这么学
    超详细 Java 15 新功能介绍
    Java 14 新功能介绍
    Java 17 将要发布,补一下 Java 13 中的新功能
    Java 8 Function 函数接口
    PO/DO/VO/DTO/BO/POJO概念与区别
  • 原文地址:https://www.cnblogs.com/zhoading/p/12157407.html
Copyright © 2011-2022 走看看