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
だからzookeeper-3.4.10のソースコードをダウンロードしてください。印刷されたスタック情報トレースによると、ソースコードのcreateコマンドの処理に実際にバグがあることがわかります。ソースコードでは、一時ノードを作成するときにcreate -eが4つの入力パラメーターである必要があると想定しています。一時ノードのデータが入力されていない場合、入力パラメーターは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の公式Webサイトにアクセスしたところ、誰かがこのバグを
https://issues.apache.org/jira/browse/ZOOKEEPER-1220
でかなり前に発行したことがわかり、ZooKeeper-3.5.0バージョンでこのバグが公式に修正されました。
つまり、ZooKeeperを3.5.0以上にアップグレードする必要があります。
ただし、ZooKeeperは同社のパブリックベーシックサービスであり、バージョンは運用保守の学生によって管理されているため、開発をアップグレードすることはできません。
一時的な解決策:public void createEphemeral(最終的な文字列パス)
をpublic void createEphemeral(最終的な文字列パス、最終的なオブジェクトデータ)に置き換え、
一時的なデータを気軽に書き込みます。
if(!exist) {
//注意,这里创建的是临时节点
//zkClient.createEphemeral(currentServiceIpNode);//zookeeper-3.4.10 以及以下版本 创建临时节点时必须写入数据, 否则无法创建成功
zkClient.createEphemeral(currentServiceIpNode, "Just Need Some Data");
}
これにより一時ノードが正常に作成されます