从Zookeeper获取简单配置

时间:2016-12-27 06:40:17

标签: java configuration apache-zookeeper

我必须从Zookeeper中获取一些配置。 我现在做什么:

ZooKeeper zk = null;
try {
    zk = new ZooKeeper(zkConnect, 1000, null);
    byte[] fetched = zk.getData(CONFIG_ZNODE_PATH, false, null);
    zk.close();
    return deserializeProps(fetched);
} finally {
    if (zk != null) {
        zk.close();
    }
}

但是我不确定我是否以正确的方式做这件简单的事情,因为在doc它说明了:

  

会话建立是异步的。此构造函数将启动与服务器的连接并立即返回 - 可能(通常)在会话完全建立之前。

这是否意味着代码无效,我只能在构造函数调用后调用getData

顺便说一句,运行代码时不会出现错误。

1 个答案:

答案 0 :(得分:0)

这里发生的是,zookeeper在后台建立与zookeeper合奏的连接。因此,当您调用方法来获取配置时,连接和会话已正确建立。

只要您拥有一个完美的网络,其中zookeeper客户端始终能够找到zookeeper服务器,这将正常工作。但是,如果您的客户端在一段时间内无法找到zookeeper服务器,这将引发异常,我猜您的操作将失败。

要解决这个问题,要么你必须等到zookeeper客户端连接如下,

private ZooKeeper zk;
final CountDownLatch connectionLatch = new CountDownLatch(1);

public void yourMethod() {

    zk = new ZooKeeper(zkConnect, 2000, new Watcher() {

        public void process(WatchedEvent we) {
            if (we.getState() == KeeperState.SyncConnected) {
                connectionLatch.countDown();
            }
        }
    });

    connectionLatch.await();

    // Now we have connected to zookeeper.
    // Now, we can fetch configuration safely.
    byte[] fetched = zk.getData(CONFIG_ZNODE_PATH, false, null);
    return deserializeProps(fetched);
}

请记住,你的方式没有错,它只是不安全。在你的情况下,它运作良好。如果网络延迟很大,这可能无法按预期工作。我的建议是一种更安全的方式。

我使用this blog post中给出的代码来解释我的建议。您也可以参考这些以便更好地理解。