如何解决java接口访问ZooKeeper时的connectionloss错误
常见错误日志如下:org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss究其原因,是因为ZooKeeper建立连接时采用异步操作,连接操作后并不能保证ZK连接已成功。如果在ZK连接成功前的这个小时间窗口去访问ZK,就会碰到如上错误。解决思路很
·
常见错误日志如下:
org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss
1. 原因:
是因为ZooKeeper建立连接时采用异步操作,连接操作后并不能保证ZK连接已成功。如果在ZK连接成功前的这个小时间窗口去访问ZK,就会碰到如上错误。
2. 解决思路
我们在新建ZK连接后要等一段时间,保证连接成功后再访问ZK。
3. 网上比较赞同的解决方案:
主要利用两个java类:
(1)java.util.concurrent.CountDownLatch:
一个同步辅助类,类似倒数计数,直到计数器为0时才能对资源“解锁”。未解锁前等待该资源的进程只能被阻塞。
public CountDownLatch(int count); /* 构造函数,参数指定计数次数 */
public void countDown(); /* 当前线程调用此函数,则计数减一 */
public void await() throws InterruptedException; /* 此函数会一直阻塞当前线程,直到计时器的值为0为止 */
(2)org.apache.zookeeper.Watcher
ZooKeeper有一个很有用的功能,就是集群上每一个变化都可以通知到自定义的Watchcer。4. 参考代码模板( 仅是模板,未经编译运行过,需稍作补充修改):
****************************************************************************************************************************
import
java.util.concurrent.CountDownLatch;
import
java.io.IOException;
import
org.apache.zookeeper.KeeperException;
import
org.apache.zookeeper.WatchedEvent;
import
org.apache.zookeeper.Watcher;
import
org.apache.zookeeper.ZooKeeper;
import
org.apache.zookeeper.Watcher.Event.KeeperState;
import
org.apache.zookeeper.ZooDefs.Ids;
public class ZkClient {
if(testZooKeeper.getState() == States.CONNECTING) {
try {
testLatch.await();
} catch (InterruptedException err) {
System.out.println("Latch exception");
}
}
}
static class ConnectedWatcher implements Watcher {
private CountDownLatch connectedLatch;
ConnectedWatcher(CountDownLatch connectedLatch) {
this.connectedLatch = connectedLatch; /* CountDownLatch实例初始化时设为1即可 */
}
@Override
public void process(WatchedEvent event) {
if (event.getState() == KeeperState.SyncConnected) {
connectedLatch.countDown(); /* ZK连接成功时,计数器由1减为0 */
}
}
}
public static void main(String args[]) throws IOException, KeeperException, InterruptedException {
try {
CountDownLatch sampleLatch = new CountDownLatch(1);
Watcher sampleWatcher = new ConnectedWatcher (sampleLatch);
zk = new ZooKeeper("127.0.0.1:2181", 30, sampleWatcher);
waitUntilConnected(zk, sampleLatch); /* 只有当ZK链接成功(状态为 SyncConnected)时,此函数调用才结束 */
/*接下来就可以继续ZK访问了,避免因为ZK未连接成功时的访问出错 */
...
} catch(Exception err) {
System.out.println(err);
}
}
}
****************************************************************************************************************************
IT人的微信自媒体--- 杰天空, 走在寻找创意的路上
发掘创意,点缀生活,品味人生。
请搜索微信订阅号: jksy_studio ,或者微信扫描下图二维码添加关注
杰天空静候您的光临。
更多推荐
已为社区贡献2条内容
所有评论(0)