2016-12-27 22 views
0

我必须从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

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

回答

0

这里发生的事情是,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给出的代码来解释我的建议。你也可以参考,以获得更好的理解。

+0

我想到了类似的实现。可能要更新我的代码,谢谢。 – Aliaxander