方法論:認(rèn)識問題啄清、分析問題藏古、解決問題。
1. 問題描述
Dubbo 應(yīng)用使用 ZooKeeper
作為注冊中心烟阐,啟動時(shí)發(fā)生該異常搬俊。
ZooKeeper和Curator的JAR版本
curator-framework-3.3.0
zookeeper-3.4.9
ZooKeeper服務(wù)器的版本: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. 問題分析
與本異常相關(guān)的關(guān)鍵源代碼:
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;
}
......
}
根據(jù)上述源代碼,問題根源是QuorumMaj類未定義單個(gè)Map參數(shù)的構(gòu)造函數(shù),而EnsembleTracker類卻引用了它
悠抹。
該問題的本質(zhì)是JAR包沖突引發(fā)的代碼不兼容問題
珠月。
4. 解決方案
- 升級 ZooKeeper JAR版本到
zookeeper-3.5.3-beta
祝玩得開心!ˇ?ˇ
云舒楔敌,2017.10.4啤挎,杭州