- 问题描述
Curator使用ZooKeeper
作为分布式锁,启动时发生该异常。
Curator 客户端版本:curator-recipes-2.10.0
ZooKeeper 服务器版本:3.4.13
$ echo stat | nc localhost 2181
Zookeeper version: 3.4.13-2d71af4dbe22557fda74f9a9b4309b15a7487f03, built on 06/29/2018 04:05 GMT
- 异常日志
Exception in thread "pool-5-thread-4789" java.lang.NoClassDefFoundError: Could not initialize class com.itstyle.seckill.distributedlock.zookeeper.ZkLockUtil
以及
org.apache.zookeeper.KeeperException$UnimplementedException: KeeperErrorCode = Unimplemented for /curator/lock/_c_9e23f33f-49e7-48df-a268-0dde3afb0e35-lock-
- 问题分析
UnimplementedException
的描述是Operation is unimplemented
,即该操作未实现异常。 最后的异常调用栈ZooKeeper.create(ZooKeeper.java:1297)
方法的源代码:
/**
* Create a node with the given path and returns the Stat of that node. The
* node data will be the given data and node acl will be the given acl.
*/
public String create(final String path, byte data[], List<ACL> acl,
CreateMode createMode, Stat stat)
throws KeeperException, InterruptedException {
final String clientPath = path;
PathUtils.validatePath(clientPath, createMode.isSequential());
final String serverPath = prependChroot(clientPath);
RequestHeader h = new RequestHeader();
h.setType(createMode.isContainer() ? ZooDefs.OpCode.createContainer : ZooDefs.OpCode.create2);
CreateRequest request = new CreateRequest();
Create2Response response = new Create2Response();
request.setData(data);
request.setFlags(createMode.toFlag());
request.setPath(serverPath);
if (acl != null && acl.size() == 0) {
throw new KeeperException.InvalidACLException();
}
request.setAcl(acl);
ReplyHeader r = cnxn.submitRequest(h, request, response, null);
if (r.getErr() != 0) {
throw KeeperException.create(KeeperException.Code.get(r.getErr()),
clientPath);
}
if (stat != null) {
DataTree.copyStat(response.getStat(), stat);
}
if (cnxn.chrootPath == null) {
return response.getPath();
} else {
return response.getPath().substring(cnxn.chrootPath.length());
}
}
从 ZooKeeper.create(ZooKeeper.java:1297)
方法看,是ZooKeeper创建节点时发生了异常。
本人使用的是zookeeper
的最新稳定版3.4.13
(最新不稳定版是3.5.X),因为使用curator
的版本必须匹配服务器上安装zookeeper
的版本,
所以curator
不能使用最新版本,否则创建节点时就会报错误。
org.apache.zookeeper.KeeperException$UnimplementedException: KeeperErrorCode = Unimplemented for /curator/test01
官方解释:
Versions
The are currently two released versions of Curator, 2.x.x and 3.x.x:
Curator 2.x.x - compatible with both ZooKeeper 3.4.x and ZooKeeper 3.5.x
Curator 3.x.x - compatible only with ZooKeeper 3.5.x and includes support for new features such as dynamic reconfiguration, etc.
Apache Curator对ZooKeeper版本兼容性ZooKeeper Version Compatibility 解释如下:
ZooKeeper 3.5.x
Curator 4.0 has a hard dependency on ZooKeeper 3.5.x
ZooKeeper 3.4.x
Curator 4.0 supports ZooKeeper 3.4.x ensembles in a soft-compatibility mode.
可以确定,问题根源是Curator的2.10.0版本无法匹配ZooKeeper服务器的3.4.13版本。
- 解决方案
- 将 Curator 版本升级到最新的 curator-recipes-4.1.0,剔除包含的zookeeper的jar,并增加zookeeper最新的3.4.13的jar
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.1.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.13</version>
</dependency>
- 或者将curator-recipes升级到2.x.x最新的 curator-recipes-2.13.0
来源:oschina
链接:https://my.oschina.net/u/3209432/blog/3015347