Spring Cloud 配置客户端
Spring Boot 应用程序可以立即利用 Spring 配置服务器(或应用程序开发者提供的其他外部属性源)。它还会获取一些与Environment
更改事件相关的额外有用功能。
Spring Boot 配置数据导入
Spring Boot 2.4 引入了一种通过spring.config.import
属性导入配置数据的新方法。这现在是绑定到配置服务器的默认方法。
要选择性地连接到配置服务器,请在 application.properties 中设置以下内容:
spring.config.import=optional:configserver:
这将连接到默认位置为“https://127.0.0.1:8888”的配置服务器。删除optional:
前缀将导致配置客户端在无法连接到配置服务器时失败。要更改配置服务器的位置,请设置spring.cloud.config.uri
或将 url 添加到spring.config.import
语句中,例如,spring.config.import=optional:configserver:http://myhost:8888
。导入属性中的位置优先于 uri 属性。
Spring Boot 配置数据通过两步过程解析配置。首先,它使用default
配置文件加载所有配置。这允许 Spring Boot 收集所有可能激活任何其他配置文件的配置。在收集所有激活的配置文件后,它将加载活动配置文件的任何其他配置。因此,您可能会看到向 Spring Cloud 配置服务器发出多个请求以获取配置。这是正常的,并且是使用spring.config.import
时 Spring Boot 加载配置的副作用。在早期版本的 Spring Cloud 配置中,只有一个请求,但这意味着您无法从来自配置服务器的配置中激活配置文件。现在,仅使用“default”配置文件的额外请求使这成为可能。
对于通过spring.config.import 导入的 Spring Boot 配置数据方法,**不需要**bootstrap 文件(属性或 yaml)。 |
配置优先引导
要使用连接到配置服务器的旧版引导方式,必须通过属性或spring-cloud-starter-bootstrap
启动器启用引导。该属性是spring.cloud.bootstrap.enabled=true
。它必须设置为系统属性或环境变量。启用引导后,类路径上具有 Spring Cloud 配置客户端的任何应用程序都将按如下方式连接到配置服务器:当配置客户端启动时,它绑定到配置服务器(通过spring.cloud.config.uri
引导配置属性)并使用远程属性源初始化 Spring Environment
。
此行为的最终结果是,所有想要使用配置服务器的客户端应用程序都需要一个bootstrap.yml
(或环境变量),其中在spring.cloud.config.uri
中设置了服务器地址(默认为“https://127.0.0.1:8888”)。
发现优先查找
除非您使用配置优先引导,否则您需要在配置属性中具有带有optional: 前缀的spring.config.import 属性。例如,spring.config.import=optional:configserver: 。 |
如果您使用DiscoveryClient
实现,例如 Spring Cloud Netflix 和 Eureka 服务发现或 Spring Cloud Consul,您可以让配置服务器向发现服务注册。
如果您更喜欢使用DiscoveryClient
来查找配置服务器,您可以通过设置spring.cloud.config.discovery.enabled=true
来实现(默认为false
)。例如,对于 Spring Cloud Netflix,您需要定义 Eureka 服务器地址(例如,在eureka.client.serviceUrl.defaultZone
中)。使用此选项的代价是在启动时需要额外的网络往返来查找服务注册。好处是,只要发现服务是一个固定点,配置服务器就可以更改其坐标。默认服务 ID 是configserver
,但您可以通过设置spring.cloud.config.discovery.serviceId
(以及在服务器上,以服务通常的方式,例如通过设置spring.application.name
)在客户端上更改它。
发现客户端实现都支持某种元数据映射(例如,对于 Eureka,我们有eureka.instance.metadataMap
)。可能需要在配置服务器的服务注册元数据中配置配置服务器的一些其他属性,以便客户端能够正确连接。如果配置服务器使用 HTTP Basic 进行保护,则可以将凭据配置为user
和password
。此外,如果配置服务器具有上下文路径,则可以设置configPath
。例如,以下 YAML 文件适用于作为 Eureka 客户端的配置服务器
eureka:
instance:
...
metadataMap:
user: osufhalskjrtl
password: lviuhlszvaorhvlo5847
configPath: /config
配置客户端快速失败
在某些情况下,如果服务无法连接到配置服务器,您可能希望使其启动失败。如果需要此行为,请设置 bootstrap 配置属性 spring.cloud.config.fail-fast=true
,使客户端以异常停止。
要使用 spring.config.import 获取类似的功能,只需省略 optional: 前缀。 |
配置客户端重试
如果您预计配置服务器在应用程序启动时可能偶尔不可用,您可以使其在失败后继续尝试。首先,您需要设置 spring.cloud.config.fail-fast=true
。然后,您需要将 spring-retry
和 spring-boot-starter-aop
添加到您的类路径中。默认行为是重试六次,初始回退间隔为 1000 毫秒,后续回退的指数乘数为 1.1。您可以通过设置 spring.cloud.config.retry.*
配置属性来配置这些属性(以及其他属性)。要使用随机指数回退策略,请将 spring.cloud.config.retry.useRandomPolicy
设置为 true
。
当 spring.cloud.config.retry.useRandomPolicy 为 true 时,即使使用随机指数回退策略,max-attempts 、initial-interval 、max-interval 和 multiplier 属性仍然有效。有关如何使用它们的详细信息,请参阅 Spring Retry 中的 ExponentialRandomBackOffPolicy 和 ExponentialBackOffPolicy 。 |
要完全控制重试行为并使用旧版 bootstrap,请添加一个类型为 RetryOperationsInterceptor 且 ID 为 configServerRetryInterceptor 的 @Bean 。Spring Retry 有一个 RetryInterceptorBuilder 支持创建它。 |
使用 spring.config.import 进行配置客户端重试
重试适用于 Spring Boot spring.config.import
语句,并且正常的属性有效。但是,如果导入语句位于配置文件中(例如 application-prod.properties
),则需要不同的方法来配置重试。配置需要作为 URL 参数放在导入语句中。
spring.config.import=configserver:http://configserver.example.com?fail-fast=true&max-attempts=10&max-interval=1500&multiplier=1.2&initial-interval=1100"
这设置了 spring.cloud.config.fail-fast=true
(请注意上面缺少的前缀)和所有可用的 spring.cloud.config.retry.*
配置属性。
查找远程配置资源
配置服务从 /{application}/{profile}/{label}
提供属性源,其中客户端应用程序中的默认绑定如下所示
-
"application" =
${spring.application.name}
-
"profile" =
${spring.profiles.active}
(实际上是Environment.getActiveProfiles()
) -
"label" = "master"
设置属性 ${spring.application.name} 时,不要在应用程序名称前添加保留字 application- ,以防止解析正确的属性源时出现问题。 |
您可以通过设置 spring.cloud.config.*
(其中 *
是 name
、profile
或 label
)来覆盖所有这些属性。label
可用于回滚到配置的先前版本。使用默认的配置服务器实现,它可以是 Git 标签、分支名称或提交 ID。标签也可以作为逗号分隔的列表提供。在这种情况下,将逐一尝试列表中的项目,直到一个成功为止。在处理功能分支时,此行为非常有用。例如,您可能希望将配置标签与您的分支对齐,但使其可选(在这种情况下,使用 spring.cloud.config.label=myfeature,develop
)。
为配置服务器指定多个 URL
为了确保高可用性,当您部署了多个配置服务器实例并预期一个或多个实例偶尔不可用或无法处理请求时(例如,如果 Git 服务器宕机),您可以指定多个 URL(作为 spring.cloud.config.uri
属性下的逗号分隔列表),或者让所有实例注册到服务注册中心(如 Eureka)(如果使用 Discovery-First Bootstrap 模式)。
spring.cloud.config.uri
下列出的 URL 将按列出的顺序尝试。默认情况下,配置客户端将尝试从每个 URL 获取属性,直到尝试成功以确保高可用性。
但是,如果您只想在配置服务器未运行时(即应用程序已退出)或发生连接超时时确保高可用性,请将 spring.cloud.config.multiple-uri-strategy
设置为 connection-timeout-only
。(spring.cloud.config.multiple-uri-strategy
的默认值为 always
。)例如,如果配置服务器返回 500(内部服务器错误)响应或配置客户端从配置服务器接收 401(由于凭据错误或其他原因),配置客户端不会尝试从其他 URL 获取属性。400 错误(可能除了 404 之外)表示用户问题而不是可用性问题。请注意,如果配置服务器设置为使用 Git 服务器并且对 Git 服务器的调用失败,则可能会发生 404 错误。
可以在单个 spring.config.import
密钥下指定多个位置,而不是 spring.cloud.config.uri
。位置将按定义的顺序处理,以后的导入优先。但是,如果 spring.cloud.config.fail-fast
为 true
,则如果第一次配置服务器调用因任何原因不成功,配置客户端将失败。如果 fail-fast
为 false
,它将尝试所有 URL,直到一个调用成功,而不管失败的原因是什么。(在 spring.config.import
下指定 URL 时,spring.cloud.config.multiple-uri-strategy
不适用。)
如果您在配置服务器上使用 HTTP 基本安全,则当前仅当您将凭据嵌入到您在 spring.cloud.config.uri
属性下指定的每个 URL 中时,才有可能支持每个配置服务器的认证凭据。如果您使用任何其他类型的安全机制,则您当前无法支持每个配置服务器的身份验证和授权。
配置超时
如果您想配置超时阈值
-
可以使用属性
spring.cloud.config.request-read-timeout
配置读取超时。 -
可以使用属性
spring.cloud.config.request-connect-timeout
配置连接超时。
安全
如果您在服务器上使用 HTTP 基本安全,客户端需要知道密码(如果用户名不是默认值,则还需要知道用户名)。您可以通过配置服务器 URI 或通过单独的用户名和密码属性指定用户名和密码,如下例所示
spring:
cloud:
config:
uri: https://user:[email protected]
以下示例显示了传递相同信息的另一种方法
spring:
cloud:
config:
uri: https://myconfig.mycompany.com
username: user
password: secret
spring.cloud.config.password
和 spring.cloud.config.username
值会覆盖 URI 中提供的任何内容。
如果您在 Cloud Foundry 上部署应用程序,提供密码的最佳方法是通过服务凭据(例如在 URI 中,因为它不需要位于配置文件中)。以下示例适用于本地和 Cloud Foundry 上名为 configserver
的用户提供的服务
spring:
cloud:
config:
uri: ${vcap.services.configserver.credentials.uri:http://user:password@localhost:8888}
如果配置服务器需要客户端 TLS 证书,您可以通过属性配置客户端 TLS 证书和信任库,如下例所示
spring:
cloud:
config:
uri: https://myconfig.myconfig.com
tls:
enabled: true
key-store: <path-of-key-store>
key-store-type: PKCS12
key-store-password: <key-store-password>
key-password: <key-password>
trust-store: <path-of-trust-store>
trust-store-type: PKCS12
trust-store-password: <trust-store-password>
需要将 spring.cloud.config.tls.enabled
设置为 true 以启用配置客户端 TLS。当省略 spring.cloud.config.tls.trust-store
时,将使用 JVM 默认信任库。spring.cloud.config.tls.key-store-type
和 spring.cloud.config.tls.trust-store-type
的默认值为 PKCS12。当省略密码属性时,将假定为空密码。
如果您使用其他形式的安全,您可能需要 向 ConfigServicePropertySourceLocator
提供 RestTemplate
(例如,通过在 bootstrap 上下文中获取它并注入它)。
健康指标
配置客户端提供一个 Spring Boot 健康指标,该指标尝试从配置服务器加载配置。可以通过设置 health.config.enabled=false
来禁用健康指标。出于性能原因,响应也会被缓存。默认缓存生存时间为 5 分钟。要更改该值,请设置 health.config.time-to-live
属性(以毫秒为单位)。
提供自定义 RestTemplate
在某些情况下,您可能需要自定义从客户端到配置服务器的请求。通常,这样做涉及传递特殊的 Authorization
标头以对服务器的请求进行身份验证。
使用配置数据提供自定义 RestTemplate
使用配置数据提供自定义 RestTemplate
时
-
创建一个实现
BootstrapRegistryInitializer
的类CustomBootstrapRegistryInitializer.javapublic class CustomBootstrapRegistryInitializer implements BootstrapRegistryInitializer { @Override public void initialize(BootstrapRegistry registry) { registry.register(RestTemplate.class, context -> { RestTemplate restTemplate = new RestTemplate(); // Customize RestTemplate here return restTemplate; }); } }
-
在
resources/META-INF
中,创建一个名为spring.factories
的文件,并指定您的自定义配置,如下例所示spring.factoriesorg.springframework.boot.BootstrapRegistryInitializer=com.my.config.client.CustomBootstrapRegistryInitializer
使用 Bootstrap 提供自定义 RestTemplate
使用 Bootstrap 提供自定义 RestTemplate
时
-
创建一个具有
PropertySourceLocator
实现的新配置 bean,如下例所示CustomConfigServiceBootstrapConfiguration.java@Configuration public class CustomConfigServiceBootstrapConfiguration { @Bean public ConfigServicePropertySourceLocator configServicePropertySourceLocator() { ConfigClientProperties clientProperties = configClientProperties(); ConfigServicePropertySourceLocator configServicePropertySourceLocator = new ConfigServicePropertySourceLocator(clientProperties); configServicePropertySourceLocator.setRestTemplate(customRestTemplate(clientProperties)); return configServicePropertySourceLocator; } }
对于添加 Authorization
标头的简化方法,可以使用spring.cloud.config.headers.*
属性。 -
在
resources/META-INF
中,创建一个名为spring.factories
的文件,并指定您的自定义配置,如下例所示spring.factoriesorg.springframework.cloud.bootstrap.BootstrapConfiguration = com.my.config.client.CustomConfigServiceBootstrapConfiguration
Vault 中的嵌套密钥
Vault 支持在存储在 Vault 中的值中嵌套密钥的功能,如下例所示
echo -n '{"appA": {"secret": "appAsecret"}, "bar": "baz"}' | vault write secret/myapp -
此命令将 JSON 对象写入您的 Vault。要在 Spring 中访问这些值,您可以使用传统的点 (.
) 注释,如下例所示
@Value("${appA.secret}")
String name = "World";
前面的代码会将 name
变量的值设置为 appAsecret
。
AOT 和原生镜像支持
从 4.0.0
开始,Spring Cloud Config Client 支持 Spring AOT 变换和 GraalVM 原生镜像。
对于 配置优先 bootstrap(使用 spring.config.use-legacy-processing=true ),AOT 和原生镜像支持不可用。 |
原生镜像不支持刷新范围。如果您要将配置客户端应用程序作为原生镜像运行,请确保将 spring.cloud.refresh.enabled 属性设置为 false 。 |
构建包含 Spring Cloud Config Client 的项目时,必须确保它连接到的配置数据源(例如 Spring Cloud Config Server、Consul、Zookeeper、Vault 等)可用。例如,如果您从 Spring Cloud Config Server 检索配置数据,请确保其实例正在运行并且可在配置客户端设置中指示的端口上访问。这是必要的,因为应用程序上下文在构建时正在被优化,并且需要解析目标环境。 |
由于 AOT 和原生模式下,配置在构建时被处理,上下文被优化,任何会影响 Bean 创建的属性(例如在引导上下文内使用的属性)都应该在构建时和运行时设置为相同的值,以避免出现意外行为。 |
由于 Config Client 在从原生镜像启动时连接到正在运行的数据源(例如 Config Server),因此快速启动时间将因此网络通信所需的时间而减慢。 |
可观测性元数据
可观测性 - 指标
下面您可以找到该项目声明的所有指标的列表。
环境仓库
围绕 EnvironmentRepository 创建的观察。
指标名称 spring.cloud.config.environment.find
(由约定类 org.springframework.cloud.config.server.environment.ObservationEnvironmentRepositoryObservationConvention
定义)。类型 timer
。
指标名称 spring.cloud.config.environment.find.active
(由约定类 org.springframework.cloud.config.server.environment.ObservationEnvironmentRepositoryObservationConvention
定义)。类型 长任务计时器
。
在启动观察后添加的 KeyValues 可能缺失于 *.active 指标中。 |
Micrometer 内部使用纳秒 作为基本单位。但是,每个后端都会确定实际的基本单位。(例如,Prometheus 使用秒) |
封闭类的全限定名 org.springframework.cloud.config.server.environment.DocumentedConfigObservation
。
所有标签都必须以spring.cloud.config.environment 前缀开头! |
名称 |
描述 |
|
正在为其查询属性的应用程序名称。 |
|
EnvironmentRepository 的实现。 |
|
正在为其查询属性的标签。 |
|
正在为其查询属性的应用程序名称。 |
可观测性 - 跨度
下面您可以找到该项目声明的所有跨度的列表。
环境仓库跨度
围绕 EnvironmentRepository 创建的观察。
跨度名称 spring.cloud.config.environment.find
(由约定类 org.springframework.cloud.config.server.environment.ObservationEnvironmentRepositoryObservationConvention
定义)。
封闭类的全限定名 org.springframework.cloud.config.server.environment.DocumentedConfigObservation
。
所有标签都必须以spring.cloud.config.environment 前缀开头! |
名称 |
描述 |
|
正在为其查询属性的应用程序名称。 |
|
EnvironmentRepository 的实现。 |
|
正在为其查询属性的标签。 |
|
正在为其查询属性的应用程序名称。 |