Spring 教程

Spring 笔记

关于 org.apache.zookeeper.KeeperException$UnimplementedException: KeeperErrorCode = Unimplemented for 的错误原因及解决方案

Spring 笔记 Spring 笔记


在 spring cloud 或 spring boot 项目中,服务依赖 zookeeper,又通过 apache curator 客户端连接 zk 时,如果版本匹配不一致,会出现兼容性问题,导致服务启动失败。

报错信息

org.apache.zookeeper.KeeperException$UnimplementedException: KeeperErrorCode = Unimplemented for /spring-cloud-services/knowledgedict/7f610178-bfa4-41f7-abbe-7653740fd35c
	at org.apache.zookeeper.KeeperException.create(KeeperException.java:103) ~[zookeeper-3.5.3-beta.jar:3.5.3-beta-8ce24f9e675cbefffb8f21a47e06b42864475a60]
	at org.apache.zookeeper.KeeperException.create(KeeperException.java:51) ~[zookeeper-3.5.3-beta.jar:3.5.3-beta-8ce24f9e675cbefffb8f21a47e06b42864475a60]
	at org.apache.zookeeper.ZooKeeper.create(ZooKeeper.java:1525) ~[zookeeper-3.5.3-beta.jar:3.5.3-beta-8ce24f9e675cbefffb8f21a47e06b42864475a60]
	at org.apache.curator.framework.imps.CreateBuilderImpl$17.call(CreateBuilderImpl.java:1181) ~[curator-framework-4.0.1.jar:4.0.1]
	at org.apache.curator.framework.imps.CreateBuilderImpl$17.call(CreateBuilderImpl.java:1158) ~[curator-framework-4.0.1.jar:4.0.1]
	at org.apache.curator.connection.StandardConnectionHandlingPolicy.callWithRetry(StandardConnectionHandlingPolicy.java:64) ~[curator-client-4.0.1.jar:na]
	at org.apache.curator.RetryLoop.callWithRetry(RetryLoop.java:100) ~[curator-client-4.0.1.jar:na]
	at org.apache.curator.framework.imps.CreateBuilderImpl.pathInForeground(CreateBuilderImpl.java:1155) ~[curator-framework-4.0.1.jar:4.0.1]
	at org.apache.curator.framework.imps.CreateBuilderImpl.protectedPathInForeground(CreateBuilderImpl.java:605) ~[curator-framework-4.0.1.jar:4.0.1]
	at org.apache.curator.framework.imps.CreateBuilderImpl.forPath(CreateBuilderImpl.java:595) ~[curator-framework-4.0.1.jar:4.0.1]
	at org.apache.curator.framework.imps.CreateBuilderImpl.forPath(CreateBuilderImpl.java:49) ~[curator-framework-4.0.1.jar:4.0.1]
	at org.apache.curator.x.discovery.details.ServiceDiscoveryImpl.internalRegisterService(ServiceDiscoveryImpl.java:236) ~[curator-x-discovery-4.0.1.jar:na]
	at org.apache.curator.x.discovery.details.ServiceDiscoveryImpl.reRegisterServices(ServiceDiscoveryImpl.java:456) ~[curator-x-discovery-4.0.1.jar:na]
	at org.apache.curator.x.discovery.details.ServiceDiscoveryImpl.access$100(ServiceDiscoveryImpl.java:58) ~[curator-x-discovery-4.0.1.jar:na]
	at org.apache.curator.x.discovery.details.ServiceDiscoveryImpl$1.stateChanged(ServiceDiscoveryImpl.java:78) ~[curator-x-discovery-4.0.1.jar:na]
	at org.apache.curator.framework.state.ConnectionStateManager$2.apply(ConnectionStateManager.java:274) [curator-framework-4.0.1.jar:4.0.1]
	at org.apache.curator.framework.state.ConnectionStateManager$2.apply(ConnectionStateManager.java:270) [curator-framework-4.0.1.jar:4.0.1]
	at org.apache.curator.framework.listen.ListenerContainer$1.run(ListenerContainer.java:93) [curator-framework-4.0.1.jar:4.0.1]
	at org.apache.curator.shaded.com.google.common.util.concurrent.MoreExecutors$DirectExecutor.execute(MoreExecutors.java:435) [curator-client-4.0.1.jar:na]
	at org.apache.curator.framework.listen.ListenerContainer.forEach(ListenerContainer.java:85) [curator-framework-4.0.1.jar:4.0.1]
	at org.apache.curator.framework.state.ConnectionStateManager.processEvents(ConnectionStateManager.java:268) [curator-framework-4.0.1.jar:4.0.1]
	at org.apache.curator.framework.state.ConnectionStateManager.access$000(ConnectionStateManager.java:44) [curator-framework-4.0.1.jar:4.0.1]
	at org.apache.curator.framework.state.ConnectionStateManager$1.call(ConnectionStateManager.java:120) [curator-framework-4.0.1.jar:4.0.1]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_241]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_241]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_241]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_241]

笔者直接用 spring cloud 对应大版本的依赖关系,zookeeper 是 3.5.3-beta 版本,curator 是 4.0.1 版本,但是 zookeeper 服务端版本是 3.4.x 版本。

报错原因

curator 和 zookeeper 版本之前有如下兼容关系:

Curator 官网说明如下:

第一种情况:

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.

第二种情况:

ZooKeeper 3.5.x
    Curator 4.0 has a hard dependency on ZooKeeper 3.5.x
    If you are using ZooKeeper 3.5.x there's nothing additional to do - just use Curator 4.0

ZooKeeper 3.4.x
    Curator 4.0 supports ZooKeeper 3.4.x ensembles in a soft-compatibility mode. To use this mode you must exclude ZooKeeper when adding Curator to your dependency management tool.

解决方法

针对笔者的问题,由于 zookeeper 服务器是 3.4.x 版本,curator 是 4.0.1 版本,将 curator 强依赖的 zookeeper 3.5.x 版本显性指定为 3.4.x 即可。

以 gradle 配置示例:

dependencies {

    xxxxxx

    compile group: 'org.apache.zookeeper', name: 'zookeeper', version: '3.4.13'

    xxxxxx

}

maven 示例如下:

<dependencies>
  ......

  <dependency>
  	<groupId>org.apache.zookeeper</groupId>
  	<artifactId>zookeeper</artifactId>
  	<version>3.4.13</version>
  </dependency>
  
  ......
</dependencies>