跳到主要内容

使用 Consul 进行分布式配置

DeepSeek V3 中英对照 Distributed Configuration with Consul

Consul 提供了一个用于存储配置和其他元数据的键/值存储。Spring Cloud Consul Config 是配置服务器和客户端的替代方案。配置在特殊的“引导”阶段加载到 Spring Environment 中。默认情况下,配置存储在 /config 文件夹中。基于应用程序的名称和活动配置文件,会创建多个 PropertySource 实例,这些实例模拟了 Spring Cloud Config 解析属性的顺序。例如,一个名为“testApp”且具有“dev”配置文件的应用程序将创建以下属性源:

config/testApp,dev/
config/testApp/
config/application,dev/
config/application/

最具体的属性源位于顶部,最不具体的位于底部。config/application 文件夹中的属性适用于所有使用 consul 进行配置的应用程序。config/testApp 文件夹中的属性仅对名为 "testApp" 的服务实例可用。

配置目前会在应用启动时被读取。向 /refresh 发送 HTTP POST 请求将导致配置被重新加载。配置监听 也会自动检测变更并重新加载应用上下文。

如何激活​

要开始使用 Consul 配置,请使用组 org.springframework.cloud 和工件 ID spring-cloud-starter-consul-config 的启动器。有关使用当前 Spring Cloud Release Train 设置构建系统的详细信息,请参阅 Spring Cloud 项目页面。

Spring Boot 配置数据导入​

Spring Boot 2.4 引入了一种通过 spring.config.import 属性导入配置数据的新方式。这现在是从 Consul 获取配置的默认方式。

要选择性地连接到 Consul,请在 application.properties 中设置以下内容:

spring.config.import=optional:consul:

这将连接到默认地址为 "http://localhost:8500" 的 Consul Agent。移除 optional: 前缀会导致 Consul Config 在无法连接到 Consul 时失败。要更改 Consul Config 的连接属性,可以设置 spring.cloud.consul.host 和 spring.cloud.consul.port,或者将主机/端口对添加到 spring.config.import 语句中,例如 spring.config.import=optional:consul:myhost:8500。import 属性中的地址优先级高于主机和端口属性。

Consul Config 将尝试从四个自动上下文中加载值,这些上下文基于 spring.cloud.consul.config.name(默认为 spring.application.name 属性的值)和 spring.cloud.consul.config.default-context(默认为 application)。如果您想指定上下文而不是使用计算出的上下文,可以将该信息添加到 spring.config.import 语句中。

spring.config.import=optional:consul:myhost:8500/contextone;/context/two

这将可选地仅从 /contextone 和 /context/two 加载配置。

备注

对于通过 spring.config.import 使用 Spring Boot Config Data 方法导入配置,不需要 bootstrap 文件(properties 或 yaml)。

自定义​

Consul Config 可以使用以下属性进行自定义:

spring:
cloud:
consul:
config:
enabled: true
prefix: configuration
defaultContext: apps
profileSeparator: '::'
警告

如果你设置了 spring.cloud.bootstrap.enabled=true 或 spring.config.use-legacy-processing=true,或者包含了 spring-cloud-starter-bootstrap,那么上述值需要放在 bootstrap.yml 中,而不是 application.yml。

  • enabled 将此值设为 "false" 将禁用 Consul 配置

  • prefix 设置配置值的基础文件夹

  • defaultContext 设置所有应用程序使用的文件夹名称

  • profileSeparator 设置用于在属性源中分隔配置文件名称的分隔符值

配置监控​

Consul 配置监视器利用了 Consul 的监视键前缀功能。配置监视器通过阻塞式 Consul HTTP API 调用来判断当前应用程序的相关配置数据是否发生变更。若检测到新的配置数据,系统将发布刷新事件。此操作等效于调用 /refresh 执行器端点。

要更改配置监视的调用频率,请修改 spring.cloud.consul.config.watch.delay。默认值为 1000,单位为毫秒。此延迟指的是上一次调用结束到下一次调用开始之间的时间间隔。

要禁用配置监视功能,请设置 spring.cloud.consul.config.watch.enabled=false。

watch 使用 Spring 的 TaskScheduler 来调度对 consul 的调用。默认情况下,它是一个 ThreadPoolTaskScheduler,其 poolSize 为 1。要更改 TaskScheduler,请创建一个类型为 TaskScheduler 的 bean,并使用 ConsulConfigAutoConfiguration.CONFIG_WATCH_TASK_SCHEDULER_NAME 常量进行命名。

YAML 或 Properties 配置格式​

将属性以 YAML 或 Properties 格式存储为一个整体,可能比存储为单独的键值对更为方便。将 spring.cloud.consul.config.format 属性设置为 YAML 或 PROPERTIES。例如,要使用 YAML:

spring:
cloud:
consul:
config:
format: YAML
警告

如果你设置了 spring.cloud.bootstrap.enabled=true 或 spring.config.use-legacy-processing=true,或者包含了 spring-cloud-starter-bootstrap,那么上述值需要放在 bootstrap.yml 中,而不是 application.yml。

YAML 必须设置在 consul 中相应的 data 键下。使用上述默认配置时,键的路径应如下所示:

config/testApp,dev/data
config/testApp/data
config/application,dev/data
config/application/data

您可以将YAML文档存储在上述任意键中。

您可以使用 spring.cloud.consul.config.data-key 来更改数据键。

使用 Config 的 git2consul​

git2consul 是一个 Consul 社区项目,它从 git 仓库加载文件到 Consul 中的各个键。默认情况下,键的名称就是文件的名称。支持 YAML 和 Properties 文件,文件扩展名分别为 .yml 和 .properties。将 spring.cloud.consul.config.format 属性设置为 FILES。例如:

spring:
cloud:
consul:
config:
format: FILES

在 /config 目录下,给定以下键,development 配置文件以及应用程序名称为 foo:

.gitignore
application.yml
bar.properties
foo-development.properties
foo-production.yml
foo.properties
master.ref

将创建以下属性源:

config/foo-development.properties
config/foo.properties
config/application.yml

每个键的值必须是一个格式正确的 YAML 或 Properties 文件。

快速失败​

在某些情况下(例如本地开发或特定的测试场景),如果 Consul 不可用于配置,不使其失败可能会更方便。设置 spring.cloud.consul.config.fail-fast=false 将导致配置模块记录警告而不是抛出异常。这将允许应用程序正常继续启动。

警告

如果你设置了 spring.cloud.bootstrap.enabled=true 或 spring.config.use-legacy-processing=true,或者包含了 spring-cloud-starter-bootstrap,那么上述值需要放在 bootstrap.yml 中,而不是 application.yml。