方法论:认识问题、分析问题、解决问题。
1. 问题描述
Dubbo 应用使用 ZooKeeper
作为注册中心,启动时发生该异常。
ZooKeeper和Curator的JAR版本
curator-framework-3.3.0
zookeeper-3.4.9
ZooKeeper服务器的版本:3.5.1-alpha
$ echo stat | nc localhost 2181
Zookeeper version: 3.5.1-alpha-1693007, built on 07/28/2015 07:19 GMT
2. 异常日志
2017-10-03 23:57:01.422 INFO 94641 --- [ main] utoConfigurationReportLoggingInitializer :
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-10-03 23:57:01.431 ERROR 94641 --- [ main] o.s.boot.SpringApplication : Application startup failed
java.lang.NoSuchMethodError: org.apache.zookeeper.server.quorum.flexible.QuorumMaj.<init>(Ljava/util/Map;)V
at org.apache.curator.framework.imps.EnsembleTracker.<init>(EnsembleTracker.java:59) ~[curator-framework-3.3.0.jar:3.3.0]
at org.apache.curator.framework.imps.CuratorFrameworkImpl.<init>(CuratorFrameworkImpl.java:158) ~[curator-framework-3.3.0.jar:3.3.0]
at org.apache.curator.framework.CuratorFrameworkFactory$Builder.build(CuratorFrameworkFactory.java:156) ~[curator-framework-3.3.0.jar:3.3.0]
at com.alibaba.dubbo.remoting.zookeeper.curator.CuratorZookeeperClient.<init>(CuratorZookeeperClient.java:36) ~[dubbo-2.5.5.jar:2.5.5]
at com.alibaba.dubbo.remoting.zookeeper.curator.CuratorZookeeperTransporter.connect(CuratorZookeeperTransporter.java:10) ~[dubbo-2.5.5.jar:2.5.5]
at com.alibaba.dubbo.remoting.zookeeper.ZookeeperTransporter$Adaptive.connect(ZookeeperTransporter$Adaptive.java) ~[dubbo-2.5.5.jar:2.5.5]
at com.alibaba.dubbo.registry.zookeeper.ZookeeperRegistry.<init>(ZookeeperRegistry.java:69) ~[dubbo-2.5.5.jar:2.5.5]
at com.alibaba.dubbo.registry.zookeeper.ZookeeperRegistryFactory.createRegistry(ZookeeperRegistryFactory.java:37) ~[dubbo-2.5.5.jar:2.5.5]
at com.alibaba.dubbo.registry.support.AbstractRegistryFactory.getRegistry(AbstractRegistryFactory.java:95) ~[dubbo-2.5.5.jar:2.5.5]
at com.alibaba.dubbo.registry.RegistryFactory$Adaptive.getRegistry(RegistryFactory$Adaptive.java) ~[dubbo-2.5.5.jar:2.5.5]
at com.alibaba.dubbo.registry.integration.RegistryProtocol.getRegistry(RegistryProtocol.java:201) ~[dubbo-2.5.5.jar:2.5.5]
at com.alibaba.dubbo.registry.integration.RegistryProtocol.export(RegistryProtocol.java:118) ~[dubbo-2.5.5.jar:2.5.5]
at com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper.export(ProtocolListenerWrapper.java:54) ~[dubbo-2.5.5.jar:2.5.5]
at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper.export(ProtocolFilterWrapper.java:92) ~[dubbo-2.5.5.jar:2.5.5]
at com.alibaba.dubbo.rpc.Protocol$Adaptive.export(Protocol$Adaptive.java) ~[dubbo-2.5.5.jar:2.5.5]
at com.alibaba.dubbo.config.ServiceConfig.doExportUrlsFor1Protocol(ServiceConfig.java:550) ~[dubbo-2.5.5.jar:2.5.5]
at com.alibaba.dubbo.config.ServiceConfig.doExportUrls(ServiceConfig.java:346) ~[dubbo-2.5.5.jar:2.5.5]
at com.alibaba.dubbo.config.ServiceConfig.doExport(ServiceConfig.java:307) ~[dubbo-2.5.5.jar:2.5.5]
at com.alibaba.dubbo.config.ServiceConfig.export(ServiceConfig.java:206) ~[dubbo-2.5.5.jar:2.5.5]
at com.alibaba.dubbo.config.spring.ServiceBean.onApplicationEvent(ServiceBean.java:109) ~[dubbo-2.5.5.jar:2.5.5]
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:393) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:347) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:883) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE]
at spring.guides.dubbo.DubboProviderApplication.main(DubboProviderApplication.java:25) [classes/:na]
3. 问题分析
与本异常相关的关键源代码:
public class EnsembleTracker implements Closeable, CuratorWatcher
{
......
private final AtomicReference<QuorumMaj> currentConfig = new AtomicReference<>(new QuorumMaj(Maps.<Long, QuorumPeer.QuorumServer>newHashMap()));
......
}
public class QuorumMaj implements QuorumVerifier {
......
int half;
/**
* Defines a majority to avoid computing it every time.
*
* @param n number of servers
*/
public QuorumMaj(int n){
this.half = n/2;
}
......
}
根据上述源代码,问题根源是QuorumMaj类未定义单个Map参数的构造函数,而EnsembleTracker类却引用了它
。
该问题的本质是JAR包冲突引发的代码不兼容问题
。
4. 解决方案
- 升级 ZooKeeper JAR版本到
zookeeper-3.5.3-beta
祝玩得开心!ˇˍˇ
云舒,2017.10.4,杭州