我正在使用以下代码从zookeeper中提取Kafka代理列表:
private static String getBrokerList() {
try {
ZooKeeper zookeeper = new ZooKeeper(zookeeperConnect, 15000, null);
List<String> ids = zookeeper.getChildren(ZkUtils.BrokerIdsPath(), false);
List<String> brokerList = new ArrayList<>();
for (String id : ids) {
String brokerInfo = new String(zookeeper.getData(ZkUtils.BrokerIdsPath() + '/' + id, false, null), Charset.forName("UTF-8"));
JsonObject jsonElement = new JsonParser().parse(brokerInfo).getAsJsonObject();
String host = jsonElement.get("host").getAsString();
brokerList.add(host + ':' + jsonElement.get("port").toString());
}
return Joiner.on(",").join(brokerList);
} catch (KeeperException | InterruptedException e) {
Throwables.propagate(e);
}
return "";
}
当一个线程一次执行代码时,上面的代码工作正常。 但是,当多个线程正在执行上述代码时,它偶尔会失败并出现以下异常:
Caused by: org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /brokers/ids
at org.apache.zookeeper.KeeperException.create(KeeperException.java:99)
at org.apache.zookeeper.KeeperException.create(KeeperException.java:51)
at org.apache.zookeeper.ZooKeeper.getChildren(ZooKeeper.java:1532)
at org.apache.zookeeper.ZooKeeper.getChildren(ZooKeeper.java:1560)
我在这里做错了什么? 我的zookeeper版本是3.4.6-1569965。
答案 0 :(得分:3)
“会话建立是异步的。这个构造函数将启动与服务器的连接并立即返回 - 可能(通常)在会话完全建立之前.watcher参数指定将通知任何状态变化的观察者。可以在构造函数调用返回之前或之后的任何时刻到来。“
你必须等待zookeeper连接完全建立: https://www.tutorialspoint.com/zookeeper/zookeeper_quick_guide.htm
向下滚动到api部分“连接到ZooKeeper Ensemble”