【问题标题】:No DiscoveryClient found during Spring bootstrap of cloud-vault-config在 cloud-vault-config 的 Spring 引导期间未找到 DiscoveryClient
【发布时间】:2021-03-02 05:23:03
【问题描述】:

我正在使用spring-cloud-starter-vault-config 从保险库中提取秘密。我可以使用 Config First Bootstrap 正常工作。当我尝试启用服务发现以便从 consul 获取保管库实例时,我收到一个错误:

Error creating bean with name 'vaultPropertySourceLocator' defined in class path resource [org/springframework/cloud/vault/config/VaultBootstrapPropertySourceConfiguration.class]: Unsatisfied dependency expressed through method 'vaultPropertySourceLocator' parameter 0
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.cloud.client.discovery.DiscoveryClient' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

在启动的引导阶段,Consul 自动配置似乎根本没有启动。

我相信我在 bootstrap.yml 中设置了所有正确的属性

spring:
  application:
    name: my-app-name
  cloud:
    consul:
      discovery:
        enabled: true
      host: localhost
      port: 8500
    vault:
      discovery:
        enabled: true
        service-id: vault
      authentication: approle
      app-role:
        role-id: my-role-id
        secret-id: my-secret-id
      kv:
        enabled: true
        application-name: ${spring.application.name}
      fail-fast: true
      scheme: http

是否有我缺少的属性或注释在引导期间启用领事?

【问题讨论】:

    标签: spring-boot spring-cloud-config spring-cloud-consul spring-cloud-vault-config


    【解决方案1】:

    既然你提到了 Config First Bootstrap (https://cloud.spring.io/spring-cloud-config/multi/multi__spring_cloud_config_client.html#config-first-bootstrap),这意味着你使用 Spring Cloud Config 而不是 Spring Cloud Consul Config?

    如果是这样,你还需要包括

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-consul-discovery</artifactId>
    </dependency>
    

    如果使用 Spring Cloud Consul Config 而不是 Spring Cloud Config(有关差异的讨论,请参阅 Difference between spring cloud config server vs consul?Spring Cloud Consul Config over Spring Cloud Config),您可能仍会遇到此问题。

    以下是使用 Spring Cloud Consul Config 的情况:

    没有提到spring cloud的版本,但是查看3.0.0版本,我看到spring.factories的bootstrap部分用于自动配置不包含文件ConsulDiscoveryClientConfiguration。这是导出 DiscoveryClient bean 的配置文件(ConsulDiscoveryClient 扩展了 DiscoveryClient)。

    public class ConsulDiscoveryClientConfiguration {
    
      ...
    
      @Bean
      @ConditionalOnMissingBean
      public ConsulDiscoveryClient consulDiscoveryClient(ConsulClient consulClient,
          ConsulDiscoveryProperties discoveryProperties) {
        return new ConsulDiscoveryClient(consulClient, discoveryProperties);
      }
    
    }
    

    ConsulDiscoveryClientConfiguration 包含在常规的 # Auto-Configuration 部分中,如下所示,但该阶段发生在 # Bootstrap Configuration 阶段之后。这些是相关的 spring.factories 文件

    org/springframework/cloud/spring-cloud-vault-config/3.0.0/spring-cloud-vault-config-3.0.0.jar!/META-INF/spring.factories

    # Auto-Configuration
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    org.springframework.cloud.vault.config.VaultReactiveAutoConfiguration,\
    org.springframework.cloud.vault.config.VaultAutoConfiguration,\
    org.springframework.cloud.vault.config.VaultHealthIndicatorAutoConfiguration
    
    # Bootstrap Configuration
    org.springframework.cloud.bootstrap.BootstrapConfiguration=\
    org.springframework.cloud.vault.config.DiscoveryClientVaultBootstrapConfiguration,\
    org.springframework.cloud.vault.config.ReactiveDiscoveryClientVaultBootstrapConfiguration,\
    org.springframework.cloud.vault.config.VaultBootstrapConfiguration,\
    org.springframework.cloud.vault.config.VaultReactiveBootstrapConfiguration,\
    org.springframework.cloud.vault.config.VaultBootstrapPropertySourceConfiguration
    
    # ConfigData Resolver
    org.springframework.boot.context.config.ConfigDataLocationResolver=\
    org.springframework.cloud.vault.config.VaultConfigDataLocationResolver
    
    # ConfigData Loader
    org.springframework.boot.context.config.ConfigDataLoader=\
    org.springframework.cloud.vault.config.VaultConfigDataLoader
    
    

    org/springframework/cloud/spring-cloud-consul-discovery/3.0.0/spring-cloud-consul-discovery-3.0.0.jar!/META-INF/spring.factories

    # Auto-Configuration
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    org.springframework.cloud.consul.discovery.configclient.ConsulConfigServerAutoConfiguration,\
    org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistrationAutoConfiguration,\
    org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistryAutoConfiguration,\
    org.springframework.cloud.consul.discovery.ConsulDiscoveryClientConfiguration,\
    org.springframework.cloud.consul.discovery.reactive.ConsulReactiveDiscoveryClientConfiguration,\
    org.springframework.cloud.consul.discovery.ConsulCatalogWatchAutoConfiguration, \
    org.springframework.cloud.consul.support.ConsulHeartbeatAutoConfiguration
    
    # Bootstrap Configuration
    org.springframework.cloud.bootstrap.BootstrapConfiguration=\
    org.springframework.cloud.consul.discovery.configclient.ConsulDiscoveryClientConfigServiceBootstrapConfiguration
    
    org.springframework.boot.Bootstrapper=\
    org.springframework.cloud.consul.discovery.configclient.ConsulConfigServerBootstrapper
    

    如您所见,spring-cloud-vault-config中的#Bootstrap Configuration包含了正确的Vault配置文件,但是spring-cloud-consul-discovery中的#Bootstrap Configuration只包含了ConsulDiscoveryClientConfigServiceBootstrapConfiguration ,这似乎适用于有人选择 Spring Cloud Config 而不是 Spring Cloud Consul Config 的情况。我这样说是因为该文件以 ConfigServicePropertySourceLocator.class

    为条件
    @ConditionalOnClass(ConfigServicePropertySourceLocator.class)
    @ConditionalOnProperty("spring.cloud.config.discovery.enabled")
    @Configuration(proxyBeanMethods = false)
    @ImportAutoConfiguration({ ConsulAutoConfiguration.class, ConsulDiscoveryClientConfiguration.class,
        ConsulReactiveDiscoveryClientConfiguration.class })
    public class ConsulDiscoveryClientConfigServiceBootstrapConfiguration {
    
    }
    

    在 spring-cloud-config-client-3.0.0.jar 中找到。如果您要包含 spring-cloud-config-client 依赖项,Vault 服务发现将起作用,因为它包含

    @ImportAutoConfiguration({ ... ConsulDiscoveryClientConfiguration.class })
    

    所需的确切配置文件。问题是,如果您包含 spring-cloud-config-client,您现在将同时使用 Spring Cloud Consul Config Spring Cloud Config,这可能不是您想要的(两者都由spring.cloud.discovery.enabled,因此尝试同时包含依赖项并关闭其中一个可能会很棘手)。

    好的,所以从我上面看到的情况来看,这看起来像是 Spring Cloud Consul 中的一个错误。我没有看到任何其他 spring.factories 可能会在 Bootstrap 配置部分加载 ConsulDiscoveryClientConfiguration。如果存在需要执行此操作的其他依赖项,我还没有看到。

    作为在 Spring Cloud Consul 中解决问题之前的临时解决方法,您可以将自己的 src/main/resources/META-INF/spring.factories 文件添加到项目中的模块中,然后包括

    org.springframework.cloud.bootstrap.BootstrapConfiguration=\
    org.springframework.cloud.consul.discovery.ConsulDiscoveryClientConfiguration
    
    

    解决了spring cloud 3.0.0版本的问题。

    【讨论】:

      猜你喜欢
      • 2018-01-12
      • 2018-05-21
      • 2018-07-25
      • 2017-06-23
      • 2023-01-20
      • 2017-08-11
      • 2022-01-08
      • 2019-08-03
      • 2018-12-15
      相关资源
      最近更新 更多