apolloconfig / apollo

Apollo is a reliable configuration management system suitable for microservice configuration management scenarios.
https://www.apolloconfig.com
Apache License 2.0
29.12k stars 10.2k forks source link

1.9.0&1.9.1版本client集成dubbo 2.6.11 property-placeholder 不能生效 #4152

Closed tietang closed 2 years ago

tietang commented 2 years ago

描述bug

1.9.0&1.9.1版本client+dubbo 2.6.11 +spring boot 使用@ImportResource 导入spring xml文件,在spring xml中的 property-placeholder 不能生效。 1.8.0 &1.7.0&1.6.2&1.5.1无此问题

复现

通过如下步骤可以复现:

  1. 集成:1.9.0&1.9.1版本client+dubbo 2.6.11 +spring boot
  2. 引入dubbo api包
  3. 创建application_dubbo.xml,并添加如下配置:

    
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
    
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"
       default-lazy-init="true">
    
    <dubbo:application name="app-web"></dubbo:application>
    
    <dubbo:registry protocol="zookeeper" address="${dubbo.zookeeper.host.port}"
                    file="${user.home}/output/app-web.cache"/>
    
    <dubbo:protocol name="dubbo" port="${dubbo.service.port}" threads="400"/>
4.  在启动main类上添加:`@ImportResource(locations = {"classpath:application_dubbo.xml"})`

**期望**

能正确获取配置,并启动应用。

**截图**

2021-12-14 16:36:05.447 [main] INFO org.apache.zookeeper.ZooKeeper 438 - Initiating client connection, connectString=${dubbo.zookeeper.host.port}:9090 sessionTimeout=60000 watcher=org.apache.curator.ConnectionState@6d4a82 2021-12-14 16:36:05.452 [main] ERROR o.a.c.f.imps.CuratorFrameworkImpl 703 - Background exception was not retry-able or retry gave up java.net.UnknownHostException: ${dubbo.zookeeper.host.port}: nodename nor servname provided, or not known at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method) at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:929) at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1324) at java.net.InetAddress.getAllByName0(InetAddress.java:1277) at java.net.InetAddress.getAllByName(InetAddress.java:1193) at java.net.InetAddress.getAllByName(InetAddress.java:1127) at org.apache.zookeeper.client.StaticHostProvider.(StaticHostProvider.java:61) at org.apache.zookeeper.ZooKeeper.(ZooKeeper.java:445) at org.apache.curator.utils.DefaultZookeeperFactory.newZooKeeper(DefaultZookeeperFactory.java:29) at org.apache.curator.framework.imps.CuratorFrameworkImpl$2.newZooKeeper(CuratorFrameworkImpl.java:213) at org.apache.curator.HandleHolder$1.getZooKeeper(HandleHolder.java:101) at org.apache.curator.HandleHolder.getZooKeeper(HandleHolder.java:57) at org.apache.curator.ConnectionState.reset(ConnectionState.java:204) at org.apache.curator.ConnectionState.start(ConnectionState.java:111) at org.apache.curator.CuratorZookeeperClient.start(CuratorZookeeperClient.java:237) at org.apache.curator.framework.imps.CuratorFrameworkImpl.start(CuratorFrameworkImpl.java:338) at com.alibaba.dubbo.remoting.zookeeper.curator.CuratorZookeeperClient.(CuratorZookeeperClient.java:69) at com.alibaba.dubbo.remoting.zookeeper.curator.CuratorZookeeperTransporter.connect(CuratorZookeeperTransporter.java:27) at com.alibaba.dubbo.remoting.zookeeper.ZookeeperTransporter$Adaptive.connect(ZookeeperTransporter$Adaptive.java) at com.alibaba.dubbo.registry.zookeeper.ZookeeperRegistry.(ZookeeperRegistry.java:69) at com.alibaba.dubbo.registry.zookeeper.ZookeeperRegistryFactory.createRegistry(ZookeeperRegistryFactory.java:38) at com.alibaba.dubbo.registry.support.AbstractRegistryFactory.getRegistry(AbstractRegistryFactory.java:96) at com.alibaba.dubbo.registry.RegistryFactory$Adaptive.getRegistry(RegistryFactory$Adaptive.java) at com.alibaba.dubbo.registry.integration.RegistryProtocol.refer(RegistryProtocol.java:276) at com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper.refer(ProtocolListenerWrapper.java:65) at com.alibaba.dubbo.qos.protocol.QosProtocolWrapper.refer(QosProtocolWrapper.java:69) at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper.refer(ProtocolFilterWrapper.java:106) at com.alibaba.dubbo.rpc.Protocol$Adaptive.refer(Protocol$Adaptive.java) at com.alibaba.dubbo.config.ReferenceConfig.createProxy(ReferenceConfig.java:400) at com.alibaba.dubbo.config.ReferenceConfig.init(ReferenceConfig.java:339) at com.alibaba.dubbo.config.ReferenceConfig.get(ReferenceConfig.java:168) at com.alibaba.dubbo.config.spring.ReferenceBean.getObject(ReferenceBean.java:67) at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:178) at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:103) at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1646) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:254) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:522) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:496) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:627) at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:171) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:318) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1268) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:551) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1131) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1059) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:518) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:496) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:627) at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:171) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:318) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1268) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:551) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:756) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:123) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:666) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:353) at org.springframework.boot.SpringApplication.run(SpringApplication.java:300) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1082) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1071)



### 额外的细节和日志

- 版本: 1.9.0,1.9.1
- 错误日志: 见上面
- 配置:
- 平台和操作系统  
Anilople commented 2 years ago

Any code can provide?

Can ${user.home} be resolved? It's a system property and isolate with apollo config.

Maybe xml can change to

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"
       default-lazy-init="true">

    <dubbo:application name="app-web"></dubbo:application>

    <dubbo:registry protocol="zookeeper" address="localhost:2181"
                    file="${user.home}/output/app-web.cache"/>

    <dubbo:protocol name="dubbo" port="8080" threads="400"/>

then test that ${user.home} can be resolved or not.

The feature of resolving placeholder is added in pr #3349

tietang commented 2 years ago

和${user.home}无关,同样的配置,1.8.0以下的版本没问题,1.9.0和1.9.1就报错,我先弄个复现的例子工程

tietang commented 2 years ago

复现代码,参考附件 spring-boot-dubbo.zip

nobodyiam commented 2 years ago

Thanks for reporting this issue, it seems an issue related to #3865, which triggers the bean initialization when apollo is starting.

@lonre would you please help to take a look at this issue?

image

image

lonre commented 2 years ago

复现代码,参考附件 spring-boot-dubbo.zip

Hi, @nobodyiam @tietang I can not reproduce it

chould you please share your copy @nobodyiam

nobodyiam commented 2 years ago

@lonre

You can use the dubbo demo project in apollo-use-cases and then follow the steps below.

  1. Modify the meta server config in com.ctrip.framework.apollo.use.cases.dubbo.service.Server and com.ctrip.framework.apollo.use.cases.dubbo.client.Consumer as follows:
    // set apollo meta server address, adjust to actual address if necessary
    System.setProperty(ConfigConsts.APOLLO_META_KEY, "http://106.54.227.205:8080");
  1. Start zookeeper in your local environment as 127.0.0.1:2181

  2. Run com.ctrip.framework.apollo.use.cases.dubbo.service.Server The server will start correctly.

  3. Run com.ctrip.framework.apollo.use.cases.dubbo.client.Consumer The consumer will fail with the wrong connection string ${zookeeper.address}. And if you add a debug point in com.alibaba.dubbo.config.RegistryConfig#setAddress, then you will see what I posted in this issue. The strange part is the server side works ok, yet I haven't figured out why.

lonre commented 2 years ago

Spring do not have api for this type of check, so the fix is a bit of dirty

nobodyiam commented 2 years ago

@tietang

1.9.2-SNAPSHOT was just released, would you please help to test with this version? In order to fetch the snapshot version, you need to add the following repositories configuration in your pom.xml

    <repositories>
        <repository>
            <id>sonatype-nexus-snapshots</id>
            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
tietang commented 2 years ago

@nobodyiam 已经验证,问题已经解决了,非常感谢,辛苦了!