上一篇记录了bootstrap启动时系统报如下异常:
No such application config! Please add <dubbo:application name="..." /> to your spring config
试了四种方式,还是没能解决这个报错问题,今天突然想到会不会跟zookeeper版本有关,之前测试alibaba dubbo用例的时候,就出现过zookeeper版本不对,导致alibaba dubbo用例的dubbo服务未能注册成功,后面把用例里面的zookeeper版本改成跟zk服务端版本一致(3.4.5),就能成注册,于是想着把bootstrap依赖的zk版本也改成3.4.5,不过查了下,bootstrap的zk版本依赖情况是这样的:
这里的bootstrap没有直接依赖zk,而是间接的依赖,这就不好改客户端的zk版本了,看来只能改服务端了,于是去zookeeper官网去找版本,没有找到3.5.6,有一个相近的3.5.9。下载下来发现可用,问题解决,具体大概如下:
- 清空旧版zookeeper中的结点内容;
- 启动admin;
- 启动alibaba dubbo test用例;
- 启动bootstrap;
注: 启动alibaba dubbo test用例和启动bootstrap的顺序不能反过来,否则会报如下错误:
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-01-30 00:26:38.197 ERROR 6712 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'syncDataService' defined in class path resource [org/dromara/soul/spring/boot/sync/data/zookeeper/ZookeeperSyncDataConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.dromara.soul.sync.data.api.SyncDataService]: Factory method 'syncDataService' threw exception; nested exception is java.lang.IllegalStateException: Failed to check the status of the service org.dromara.soul.examples.dubbo.api.service.DubboMultiParamService. No provider available for the service org.dromara.soul.examples.dubbo.api.service.DubboMultiParamService from the url zookeeper://localhost:2181/com.alibaba.dubbo.registry.RegistryService?application=soul_proxy&dubbo=2.0.2&generic=true&interface=org.dromara.soul.examples.dubbo.api.service.DubboMultiParamService&loadbalance=random&pid=6712&protocol=dubbo®ister.ip=172.30.82.27&retries=2&side=consumer&timeout=10000×tamp=1611937596814 to the consumer 172.30.82.27 use dubbo version 2.6.5
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:656) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:636) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:66) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.dromara.soul.bootstrap.SoulBootstrapApplication.main(SoulBootstrapApplication.java:37) [classes/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.dromara.soul.sync.data.api.SyncDataService]: Factory method 'syncDataService' threw exception; nested exception is java.lang.IllegalStateException: Failed to check the status of the service org.dromara.soul.examples.dubbo.api.service.DubboMultiParamService. No provider available for the service org.dromara.soul.examples.dubbo.api.service.DubboMultiParamService from the url zookeeper://localhost:2181/com.alibaba.dubbo.registry.RegistryService?application=soul_proxy&dubbo=2.0.2&generic=true&interface=org.dromara.soul.examples.dubbo.api.service.DubboMultiParamService&loadbalance=random&pid=6712&protocol=dubbo®ister.ip=172.30.82.27&retries=2&side=consumer&timeout=10000×tamp=1611937596814 to the consumer 172.30.82.27 use dubbo version 2.6.5
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:651) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
... 19 common frames omitted
Caused by: java.lang.IllegalStateException: Failed to check the status of the service org.dromara.soul.examples.dubbo.api.service.DubboMultiParamService. No provider available for the service org.dromara.soul.examples.dubbo.api.service.DubboMultiParamService from the url zookeeper://localhost:2181/com.alibaba.dubbo.registry.RegistryService?application=soul_proxy&dubbo=2.0.2&generic=true&interface=org.dromara.soul.examples.dubbo.api.service.DubboMultiParamService&loadbalance=random&pid=6712&protocol=dubbo®ister.ip=172.30.82.27&retries=2&side=consumer&timeout=10000×tamp=1611937596814 to the consumer 172.30.82.27 use dubbo version 2.6.5
at com.alibaba.dubbo.config.ReferenceConfig.createProxy(ReferenceConfig.java:422) ~[dubbo-2.6.5.jar:2.6.5]
at com.alibaba.dubbo.config.ReferenceConfig.init(ReferenceConfig.java:333) ~[dubbo-2.6.5.jar:2.6.5]
at com.alibaba.dubbo.config.ReferenceConfig.get(ReferenceConfig.java:163) ~[dubbo-2.6.5.jar:2.6.5]
at org.dromara.soul.plugin.alibaba.dubbo.cache.ApplicationConfigCache.build(ApplicationConfigCache.java:166) ~[classes/:na]
at org.dromara.soul.plugin.alibaba.dubbo.cache.ApplicationConfigCache.initRef(ApplicationConfigCache.java:130) ~[classes/:na]
at org.dromara.soul.plugin.alibaba.dubbo.subscriber.AlibabaDubboMetaDataSubscriber.onSubscribe(AlibabaDubboMetaDataSubscriber.java:45) ~[classes/:na]
at org.dromara.soul.sync.data.zookeeper.ZookeeperSyncDataService.lambda$29(ZookeeperSyncDataService.java:342) ~[classes/:na]
at java.util.ArrayList.forEach(ArrayList.java:1249) ~[na:1.8.0_60]
at org.dromara.soul.sync.data.zookeeper.ZookeeperSyncDataService.lambda$28(ZookeeperSyncDataService.java:342) ~[classes/:na]
at java.util.Optional.ifPresent(Optional.java:159) ~[na:1.8.0_60]
at org.dromara.soul.sync.data.zookeeper.ZookeeperSyncDataService.cacheMetaData(ZookeeperSyncDataService.java:342) ~[classes/:na]
at org.dromara.soul.sync.data.zookeeper.ZookeeperSyncDataService.lambda$4(ZookeeperSyncDataService.java:152) ~[classes/:na]
at java.util.ArrayList.forEach(ArrayList.java:1249) ~[na:1.8.0_60]
at org.dromara.soul.sync.data.zookeeper.ZookeeperSyncDataService.watchMetaData(ZookeeperSyncDataService.java:150) ~[classes/:na]
at org.dromara.soul.sync.data.zookeeper.ZookeeperSyncDataService.<init>(ZookeeperSyncDataService.java:74) ~[classes/:na]
at org.dromara.soul.spring.boot.sync.data.zookeeper.ZookeeperSyncDataConfiguration.syncDataService(ZookeeperSyncDataConfiguration.java:62) ~[classes/:na]
at org.dromara.soul.spring.boot.sync.data.zookeeper.ZookeeperSyncDataConfiguration$$EnhancerBySpringCGLIB$$5dc4e77b.CGLIB$syncDataService$0(<generated>) ~[classes/:na]
at org.dromara.soul.spring.boot.sync.data.zookeeper.ZookeeperSyncDataConfiguration$$EnhancerBySpringCGLIB$$5dc4e77b$$FastClassBySpringCGLIB$$80db14fc.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.dromara.soul.spring.boot.sync.data.zookeeper.ZookeeperSyncDataConfiguration$$EnhancerBySpringCGLIB$$5dc4e77b.syncDataService(<generated>) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_60]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_60]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_60]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_60]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
... 20 common frames omitted
上述错误的原因我还没仔细研究,待后续可以进一步研究。
之后进行dubbo服务代理功能测试,功能正常,包括在admin端修改dubbo元数据配置,也能在bootstrap端生效,具体机制待下一篇继续分析。
另外,上篇文章中的四种方法,前三种都是想要补上dubbo.application.name
这个配置,认为是启动后没有扫描到该配置,在我升级问题解决之后,我又去断点排查这个dubbo:application name
到底实际值是什么,排查结果如下图:
原来dubbo:application name
的值是soul_proxy
,代码搜索一番,发现是在ApplicationConfigCache类的如下方法中:
public void init(final DubboRegisterConfig dubboRegisterConfig) {
if (applicationConfig == null) {
applicationConfig = new ApplicationConfig("soul_proxy");
}
if (registryConfig == null) {
registryConfig = new RegistryConfig();
registryConfig.setProtocol(dubboRegisterConfig.getProtocol());
registryConfig.setId("soul_proxy");
registryConfig.setRegister(false);
registryConfig.setAddress(dubboRegisterConfig.getRegister());
Optional.ofNullable(dubboRegisterConfig.getGroup()).ifPresent(registryConfig::setGroup);
}
}
至于上篇中前三种方法为什么没生效还是存疑,因为按照上图的逻辑,如果applicattion为空,还是会去取dubbo.application.name
这个配置值。
总结
这个问题表面上是解决了,但是是通过一些灵感排查出来的,不是一个通用的套路,需要对问题根因进一步分析,得出一个比较通用的方法。