我必须从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
?
顺便说一句,运行代码时不会出现错误。
答案 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中给出的代码来解释我的建议。您也可以参考这些以便更好地理解。