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

  • 相关阅读:
    事务传播机制,搞懂。
    洛谷 P1553 数字反转(升级版) 题解
    洛谷 P1200 [USACO1.1]你的飞碟在这儿Your Ride Is Here 题解
    洛谷 P1055 ISBN号码 题解
    洛谷 P2141 珠心算测验 题解
    洛谷 P1047 校门外的树 题解
    洛谷 P1980 计数问题 题解
    洛谷 P1008 三连击 题解
    HDU 1013 题解
    HDU 1012 题解
  • 原文地址:https://www.cnblogs.com/zhoading/p/12157407.html
Copyright © 2011-2022 走看看