2016-12-27 31 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