使用Curator实现的zookeeper分布式锁出现的Unimplemented for {root.path}

南笙酒味 提交于 2019-11-26 17:05:07
  1. 问题描述
    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
  1. 异常日志
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-
  1. 问题分析 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版本。

  1. 解决方案
  • 将 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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!