在用ZooKeeper的API 创建临时节点时,试了好几次都不成功
zkClient.createEphemeral(currentServiceIpNode)
于是使用/zookeeper-3.4.10/bin/zkCli.sh 运行命令行尝试创建临时节点
[zk: localhost:2181(CONNECTED) 2] create -e /zk_demo/tempData
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at org.apache.zookeeper.ZooKeeperMain.processZKCmd(ZooKeeperMain.java:706)
at org.apache.zookeeper.ZooKeeperMain.processCmd(ZooKeeperMain.java:599)
at org.apache.zookeeper.ZooKeeperMain.executeLine(ZooKeeperMain.java:371)
at org.apache.zookeeper.ZooKeeperMain.run(ZooKeeperMain.java:331)
at org.apache.zookeeper.ZooKeeperMain.main(ZooKeeperMain.java:290)
ZooKeeperMain.java 报错 ArrayIndexOutOfBoundsException
于是download了zookeeper-3.4.10的源代码。根据打印的堆栈信息追踪,发现源码中对于create这个命令的处理确实有个bug, 源码中假定了create -e 创建临时节点时一定是四个输入参数。当没有输入该临时节点的数据时,输入参数只有3个 args[0]=“create” args[1]= “-e” args[2]= “/zk_demo/tempData” args[3]则会越界。
于是试了下创建时一并写入临时节点数据:果然就是成功的。
[zk: localhost:2181(CONNECTED) 0] create -e /zk_demo/tempData tempdata
Created /zk_demo/tempData
[zk: localhost:2181(CONNECTED) 1] ls /zk_demo/tempData
[]
[zk: localhost:2181(CONNECTED) 2] get /zk_demo/tempData
tempdata
cZxid = 0x79d4
ctime = Mon Jan 07 21:37:06 CST 2019
然后我去Apache ZooKeeper的官网,发现早就有人issue了这个bug
https://issues.apache.org/jira/browse/ZOOKEEPER-1220
并且官方在ZooKeeper-3.5.0版本中修复了这个bug。
也就是说,需要升级ZooKeeper到3.5.0以上。
但是ZooKeeper作为公司的公共基础服务,版本由运维的同学统一管理,开发不可以冒然去升级。
临时解决办法:
用 public void createEphemeral(final String path, final Object data) 替换
public void createEphemeral(final String path) 随便写个临时数据。
if(!exist) {
//注意,这里创建的是临时节点
//zkClient.createEphemeral(currentServiceIpNode);//zookeeper-3.4.10 以及以下版本 创建临时节点时必须写入数据, 否则无法创建成功
zkClient.createEphemeral(currentServiceIpNode, "Just Need Some Data");
}
这样创建临时节点就成功了