Во время весенней начальной загрузки cloud-vault-config не найден DiscoveryClient.

Я использую spring-cloud-starter-vault-config для извлечения секретов из хранилища. Я могу заставить это работать нормально с Config First Bootstrap. Когда я пытаюсь включить обнаружение службы, чтобы получить экземпляры хранилища от консула, я получаю сообщение об ошибке:

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

Есть ли свойство или какая-то аннотация, которую мне не хватает, чтобы включить консула во время начальной загрузки?




Ответы (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 (см. Разница между spring облачный сервер конфигурации против консула? и Spring Cloud Consul Config over Spring Cloud Config для обсуждения различий), вы все еще можете столкнуться с этой проблемой.

Ниже приведены случаи использования Spring Cloud Consul Config:

Там нет упоминания о версии весеннего облака, но, глядя на версию 3.0.0, я вижу, что раздел начальной загрузки spring.factories, используемый для автоматической настройки, не включает файл ConsulDiscoveryClientConfiguration. Это файл конфигурации, который экспортирует bean-компонент DiscoveryClient (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

Как видите, конфигурация # Bootstrap в spring-cloud-vault-config включает правильные файлы конфигурации Vault, но конфигурация # Bootstrap в spring-cloud-consul-discovery включает только 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, которые потенциально могли бы загрузить ConsulDiscoveryClientConfiguration в разделе конфигурации Bootstrap. Если существует какая-то другая необходимая зависимость, которая сделает это, я ее не видел.

В качестве временного обходного пути, пока проблема не будет устранена в Spring Cloud Consul, вы можете добавить свой собственный файл src/main/resources/META-INF/spring.factories в модуль вашего проекта и включить

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

Это решает проблему весенней облачной версии 3.0.0.

person Ulises Ortiz    schedule 12.03.2021