我已经在开发中使用ZooKeeper一段时间了,但我似乎没有得到的一件事是,在创建程序时,如何无法指定超时(至少我不知道)。与ZooKeeper服务器的连接,例如:
ZooKeeper zoo;
final CountDownLatch connectedSignal = new CountDownLatch(1);
zoo = new ZooKeeper("localhost:2182", 5000, new Watcher() {
public void process(WatchedEvent we) {
if (we.getState() == KeeperState.SyncConnected) {
connectedSignal.countDown();
}
if (we.getState() == KeeperState.Disconnected) {
connectedSignal.countDown();
}
if (we.getType() == Event.EventType.None) {
connectedSignal.countDown();
}
}
});
System.out.println("in watcher");
connectedSignal.await();
请注意,如果ZooKeeper服务器已关闭,因此似乎不会发生超时,因此不会引发异常,并且我的代码始终保持等待倒计时闩锁。我也尝试过在zoo.cfg中设置此属性,但没有任何效果:
zookeeper.connection.timeout.ms=5000
需要有关Java API for ZooKeeper中是否提供某种方法来检查是否无法创建到ZooKeeper服务器的成功连接的帮助?注意,我知道我们可以通过executorservice和futures做到这一点,但是我需要API中提供的方法吗?
答案 0 :(得分:2)
创建ZooKeeper对象时,它还将创建两个线程:IO线程和事件线程。 IO线程将执行会话维护,例如重新连接到ZooKeeper服务器并维护心跳。
在上面的代码中,5000
是会话超时值,它可以正常工作!如果启用日志记录,则会找到心跳日志,
org.apache.zookeeper.ClientCnxn - Got ping response for sessionid 0x...
并且在断开连接时
org.apache.zookeeper.ClientCnxn - Session 0x... for server null, unexpected error, closing socket connection and attempting reconnect...`
现在,我们需要知道Watch有一些局限性
从服务器断开连接时(例如,服务器发生故障时),直到重新建立连接后,您才能获得任何监视。
由于断开连接后我们无法收到任何观察者事件,因此connectedSignal.await()
在实践中可能会有些危险。您可以尝试使用超时的版本connectedSignal.await(5000)
,或者等到连接恢复。
如果要监视与ZK服务器的连接,可以生成一个单独的线程,并定期运行zoo.getState()
以查看当前状态。