在 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>