ZooKeeper构建应用之配置服务器

本文介绍如何使用ZooKeeper进行配置信息的集中管理和共享。通过示例代码展示配置的读写逻辑封装,以及如何实现配置更新和监视。适用于分布式应用的开发者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

配置信息的集中管理与共享是分布式应用的基本需求。对于此类需求,ZooKeeper可以提供两个层面的特性。一个是提供高可用存储服务,允许分布式应用的参与者更新、读取ZooKeeper中的配置信息。另一个是主动配置服务,当ZooKeeper中的配置信息发生变更时,主动通知设置了监视器的客户端,客户端收到通知后,立刻执行相应操作。

简化起见,本示例有两个前置条件。
第一,配置项的名称直接使用znode的路径表示,而znode中存储的字符串值就是配置项的值。
第二,在任何时间,只有单个客户端对配置执行更新操作。

对ZooKeeper执行读写逻辑封装在ActiveKeyValues中,代码如下:

public class ActiveKeyValueStore extends ConnectionWatcher {
    private static final charset CHARSET = charset.forName("UTF-8");

    public void write(String path, String value) throws InterruptedException,
        KeeperException {
      Stat stat = zk.exists(path, false);
      if (stat == null) {
        zk.create(path, value.getBytes(CHARSET), Ids.OPEN_ACL_UNSAFE,
            CreateMode.PERSISTENT);
       } else {
          zk.setData(path, value.getBytes(CHARSET), -1);
       }
    }

    public String read(String path, Watcher watcher) throws InteruptedException,
        KeeperException {
      byte[] data = zk.getData(path, watcher, null/*stat*/);
      return new String(data, CHARSET);
    }
}

以上代码中,write方法负责写操作,如果znode已经存在则直接设置其值,如果不存在先创建znode再设置其值。写操作返回znode中保存的值,最重要的是read方法中的Wacher参数,读客户端需要注册此监视器以便接收通知。ConnectionWatcher基类负责创建ZooKeeper实例、用户身份认证及与ZooKeeper服务器的连接。

ConfigUpdater类按随机时间间隔更新ZooKeeper中的配置项,充当更新配置客户端,代码如下:

public class ConfigUpdate {
    public static final String PATH = "/config";

    private ActiveKeyValueStore store;
    private Random random = new Random();

    public ConfigUpdater(String hosts) throws IOException, InterruptedException {
        store = new ActiveKeyValueStore();
        store.connect(hosts);
    }

    public void run throws InterruptedException, KeeperException {
        while (ture) {
          String value = random.nextInt(100) + '';
          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 Exception {
        ConfigUpdater configUpdater = new ConfigUpdater(args[0]);
        configUpdater.run();
    }
}

ConfigWatcher作为配置服务的读客户端,代码如下:

public class ConfigWatcher implements Watcher {

    private ActiveKeyValueStore store;

    public configWatcher(String hosts) throws IOException, InterreptedException {
        store = new ActiveKeyValueStore();
        store.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);
    }

    @Override
    public void process(WatcherEvent event) {
        if (event.getType() == EventType.NodeDataChanged) {
            try {
                displayConfig();
            } catch (InterruptedException e) {
                System.err.println("Interrupted. Exiting.");
                Thread.currentThread().interrupted();
            } catch (KeeperException e) {
                System.err.printf("KeeperException: %s. Exiting.\n", e);
            }
        }
    }

    public static void main(String[] args) throws Exception {
        ConfigWatcher configWatcher = new ConfigWatcher(args[0]);
        configWatcher.displayConfig();

        Thread.sleep(Long.MAX_VALUE);
    }
}

代码中的主要逻辑在process中实现,当配置发生变更时,客户端收到通知后显示新的配置内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值