4.0.5

Spring Cloud Config 为分布式系统中的外部化配置提供服务器端和客户端支持。通过配置服务器,您可以集中管理所有环境中应用程序的外部属性。客户端和服务器上的概念都与 Spring EnvironmentPropertySource 抽象完全相同,因此它们非常适合 Spring 应用程序,但可以与任何语言运行的任何应用程序一起使用。随着应用程序通过部署管道从开发到测试再到生产,您可以管理这些环境之间的配置,并确保应用程序在迁移时拥有运行所需的一切。服务器存储后端的默认实现使用 git,因此它很容易支持配置环境的标记版本,并且可以通过各种工具来管理内容。添加替代实现并使用 Spring 配置进行插件化非常容易。

快速入门

本快速入门将引导您使用 Spring Cloud Config Server 的服务器和客户端。

首先,启动服务器,如下所示:

$ cd spring-cloud-config-server
$ ../mvnw spring-boot:run

服务器是一个 Spring Boot 应用程序,如果您愿意,可以从您的 IDE 运行它(主类是 ConfigServerApplication)。

接下来,尝试一个客户端,如下所示:

$ curl localhost:8888/foo/development
{
  "name": "foo",
  "profiles": [
    "development"
  ]
  ....
  "propertySources": [
    {
      "name": "https://github.com/spring-cloud-samples/config-repo/foo-development.properties",
      "source": {
        "bar": "spam",
        "foo": "from foo development"
      }
    },
    {
      "name": "https://github.com/spring-cloud-samples/config-repo/foo.properties",
      "source": {
        "foo": "from foo props",
        "democonfigclient.message": "hello spring io"
      }
    },
    ....

定位属性源的默认策略是克隆一个 git 仓库(位于 spring.cloud.config.server.git.uri)并使用它来初始化一个迷你的 SpringApplication。迷你应用程序的 Environment 用于枚举属性源并将其发布到 JSON 端点。

HTTP 服务具有以下形式的资源:

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties

例如:

curl localhost:8888/foo/development
curl localhost:8888/foo/development/master
curl localhost:8888/foo/development,db/master
curl localhost:8888/foo-development.yml
curl localhost:8888/foo-db.properties
curl localhost:8888/master/foo-db.properties

其中 application 作为 spring.config.name 注入到 SpringApplication 中(在常规 Spring Boot 应用程序中通常是 application),profile 是一个活动配置文件(或逗号分隔的属性列表),label 是一个可选的 git 标签(默认为 master)。

Spring Cloud Config Server 从各种来源拉取远程客户端的配置。以下示例从 git 仓库(必须提供)获取配置,如以下示例所示:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo

其他来源包括任何 JDBC 兼容数据库、Subversion、Hashicorp Vault、Credhub 和本地文件系统。

客户端用法

要在应用程序中使用这些功能,您可以将其构建为依赖于 spring-cloud-config-client 的 Spring Boot 应用程序(有关示例,请参阅 config-client 的测试用例或示例应用程序)。添加依赖项最方便的方法是使用 Spring Boot starter org.springframework.cloud:spring-cloud-starter-config。Maven 用户还有一个父 pom 和 BOM (spring-cloud-starter-parent),Gradle 和 Spring CLI 用户有一个 Spring IO 版本管理属性文件。以下示例显示了典型的 Maven 配置:

pom.xml
   <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>{spring-boot-docs-version}</version>
       <relativePath /> <!-- lookup parent from repository -->
   </parent>

<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-dependencies</artifactId>
			<version>{spring-cloud-version}</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

<dependencies>
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-config</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>
</dependencies>

<build>
	<plugins>
           <plugin>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-maven-plugin</artifactId>
           </plugin>
	</plugins>
</build>

   <!-- repositories also needed for snapshots and milestones -->

现在您可以创建一个标准的 Spring Boot 应用程序,例如以下 HTTP 服务器

@SpringBootApplication
@RestController
public class Application {

    @RequestMapping("/")
    public String home() {
        return "Hello World!";
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

当此 HTTP 服务器运行时,它会从默认的本地配置服务器(如果正在运行)获取端口 8888 上的外部配置。要修改启动行为,您可以使用 application.properties 更改配置服务器的位置,如以下示例所示:

spring.config.import=optional:configserver:http://myconfigserver.com

默认情况下,如果没有设置应用程序名称,则使用 application。要修改名称,可以将以下属性添加到 application.properties 文件中:

spring.application.name: myapp
设置属性 ${spring.application.name} 时,请勿使用保留字 application- 作为应用程序名称的前缀,以防止解析正确的属性源时出现问题。

配置服务器属性在 /env 端点中显示为高优先级属性源,如以下示例所示。

$ curl localhost:8080/env
{
  "activeProfiles": [],
  {
    "name": "servletContextInitParams",
    "properties": {}
  },
  {
    "name": "configserver:https://github.com/spring-cloud-samples/config-repo/foo.properties",
    "properties": {
      "foo": {
        "value": "bar",
        "origin": "Config Server https://github.com/spring-cloud-samples/config-repo/foo.properties:2:12"
      }
    }
  },
  ...
}

一个名为 configserver:<远程仓库的 URL>/<文件名> 的属性源包含 foo 属性,其值为 bar

属性源名称中的 URL 是 git 仓库,而不是配置服务器 URL。
如果使用 Spring Cloud Config Client,您需要设置 spring.config.import 属性才能绑定到 Config Server。您可以在Spring Cloud Config 参考指南中阅读更多信息。

Spring Cloud Config Server

Spring Cloud Config Server 提供了一个基于 HTTP 资源的外部配置 API(名称-值对或等效的 YAML 内容)。通过使用 @EnableConfigServer 注解,服务器可以嵌入到 Spring Boot 应用程序中。因此,以下应用程序是配置服务器:

ConfigServer.java
@SpringBootApplication
@EnableConfigServer
public class ConfigServer {
  public static void main(String[] args) {
    SpringApplication.run(ConfigServer.class, args);
  }
}

像所有 Spring Boot 应用程序一样,它默认在端口 8080 上运行,但您可以通过多种方式将其切换到更传统的端口 8888。最简单的方法是使用 spring.config.name=configserver 启动它(Config Server jar 中有一个 configserver.yml),它也设置了默认的配置仓库。另一种方法是使用您自己的 application.properties,如以下示例所示:

application.properties
server.port: 8888
spring.cloud.config.server.git.uri: file://${user.home}/config-repo

其中 ${user.home}/config-repo 是一个包含 YAML 和属性文件的 git 仓库。

在 Windows 上,如果文件 URL 是绝对路径并带有驱动器前缀(例如,file:///${user.home}/config-repo),则需要在文件 URL 中多加一个 “/”。

以下列表显示了在上述示例中创建 git 仓库的方法:

$ cd $HOME
$ mkdir config-repo
$ cd config-repo
$ git init .
$ echo info.foo: bar > application.properties
$ git add -A .
$ git commit -m "Add application.properties"
将本地文件系统用于 Git 仓库仅用于测试。您应该使用服务器来托管生产环境中的配置仓库。
如果您的配置仓库只包含文本文件,则首次克隆会很快且高效。如果存储二进制文件,尤其是大型文件,您可能会在首次请求配置时遇到延迟,或者在服务器中遇到内存不足错误。

环境仓库

Config Server 的配置数据应该存储在哪里?管理此行为的策略是 EnvironmentRepository,它提供 Environment 对象。此 Environment 是 Spring Environment 领域的一个浅层副本(包括 propertySources 作为主要功能)。Environment 资源由三个变量参数化:

  • {application},在客户端映射到 spring.application.name

  • {profile},在客户端映射到 spring.profiles.active(逗号分隔列表)。

  • {label},这是一个服务器端功能,用于标记“版本化”的配置文件集。

仓库实现通常表现得像一个 Spring Boot 应用程序,从 spring.config.name 等于 {application} 参数和 spring.profiles.active 等于 {profiles} 参数的配置文件中加载配置。配置文件的优先级规则也与常规 Spring Boot 应用程序中的相同:活动配置文件优先于默认值,如果有多个配置文件,则最后一个胜出(类似于向 Map 中添加条目)。

以下示例客户端应用程序具有此引导配置:

spring:
  application:
    name: foo
  profiles:
    active: dev,mysql

(与 Spring Boot 应用程序一样,这些属性也可以通过环境变量或命令行参数设置)。

如果仓库是基于文件的,服务器会从 application.yml(所有客户端共享)和 foo.ymlfoo.yml 优先)创建 Environment。如果 YAML 文件中包含指向 Spring 配置文件的文档,则这些配置文件将以更高的优先级应用(按列出的配置文件顺序)。如果存在特定于配置文件的 YAML(或属性)文件,则这些文件也将以比默认值更高的优先级应用。更高的优先级意味着在 Environment 中更早列出的 PropertySource。(这些相同的规则也适用于独立的 Spring Boot 应用程序。)

您可以将 spring.cloud.config.server.accept-empty 设置为 false,这样,如果找不到应用程序,服务器将返回 HTTP 404 状态。默认情况下,此标志设置为 true

您不能将 spring.main.* 属性放在远程 EnvironmentRepository 中。这些属性用作应用程序初始化的一部分。

Git 后端

EnvironmentRepository 的默认实现使用 Git 后端,这对于管理升级、物理环境和审计更改非常方便。要更改仓库位置,您可以在 Config Server 中设置 spring.cloud.config.server.git.uri 配置属性(例如在 application.yml 中)。如果您将其设置为 file: 前缀,它应该可以从本地仓库工作,这样您就可以快速轻松地开始,而无需服务器。但是,在这种情况下,服务器直接在本地仓库上操作而无需克隆它(如果它不是裸仓库也没关系,因为 Config Server 从不更改“远程”仓库)。要扩展 Config Server 并使其高可用,您需要让服务器的所有实例都指向同一个仓库,因此只有共享文件系统才能工作。即使在这种情况下,最好也使用 ssh: 协议来访问共享文件系统仓库,以便服务器可以克隆它并使用本地工作副本作为缓存。

此仓库实现将 HTTP 资源的 {label} 参数映射到 git 标签(提交 ID、分支名称或标签)。如果 git 分支或标签名称包含斜杠 (/),则 HTTP URL 中的标签应改用特殊字符串 (_) 指定(以避免与其他 URL 路径混淆)。例如,如果标签是 foo/bar,则替换斜杠将导致以下标签:foo(_)bar。特殊字符串 (_) 的包含也可以应用于 {application} 参数。如果您使用命令行客户端(例如 curl),请小心 URL 中的括号——您应该使用单引号 ('') 将它们从 shell 中转义。

跳过 SSL 证书验证

可以通过将 git.skipSslValidation 属性设置为 true(默认值为 false)来禁用配置服务器对 Git 服务器 SSL 证书的验证。

spring:
  cloud:
    config:
      server:
        git:
          uri: https://example.com/my/repo
          skipSslValidation: true
设置 HTTP 连接超时

您可以配置配置服务器等待获取 HTTP 连接的时间(以秒为单位)。使用 git.timeout 属性(默认值为 5)。

spring:
  cloud:
    config:
      server:
        git:
          uri: https://example.com/my/repo
          timeout: 4
Git URI 中的占位符

Spring Cloud Config Server 支持带有 {application}{profile} 占位符的 git 仓库 URL(如果需要,还可以使用 {label},但请记住,标签无论如何都作为 git 标签应用)。因此,您可以通过使用类似于以下的结构来支持“每个应用程序一个仓库”策略:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/myorg/{application}

您还可以通过使用类似的模式但带有 {profile} 来支持“每个配置文件一个仓库”策略。

此外,在 {application} 参数中使用特殊字符串 "(_)" 可以支持多个组织,如以下示例所示:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/{application}

其中 {application} 在请求时以以下格式提供:organization(_)application

模式匹配和多个仓库

Spring Cloud Config 还支持通过对应用程序和配置文件名进行模式匹配来满足更复杂的需求。模式格式是逗号分隔的 {application}/{profile} 名称列表,带通配符(请注意,以通配符开头的模式可能需要加引号),如以下示例所示:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          repos:
            simple: https://github.com/simple/config-repo
            special:
              pattern: special*/dev*,*special*/dev*
              uri: https://github.com/special/config-repo
            local:
              pattern: local*
              uri: file:/home/configsvc/config-repo

如果 {application}/{profile} 不匹配任何模式,它将使用 spring.cloud.config.server.git.uri 下定义的默认 URI。在上面的示例中,对于“simple”仓库,模式是 simple/*(它只匹配所有配置文件中名为 simple 的一个应用程序)。“local”仓库匹配所有配置文件中以 local 开头的所有应用程序名称(/* 后缀会自动添加到任何没有配置文件匹配器的模式中)。

“simple”示例中使用的“一行式”快捷方式只能在唯一要设置的属性是 URI 时使用。如果您需要设置其他任何内容(凭据、模式等),则需要使用完整形式。

仓库中的 pattern 属性实际上是一个数组,因此您可以使用 YAML 数组(或属性文件中的 [0][1] 等后缀)来绑定多个模式。如果您将使用多个配置文件运行应用程序,则可能需要这样做,如以下示例所示:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          repos:
            development:
              pattern:
                - '*/development'
                - '*/staging'
              uri: https://github.com/development/config-repo
            staging:
              pattern:
                - '*/qa'
                - '*/production'
              uri: https://github.com/staging/config-repo
Spring Cloud 会猜测,如果一个包含配置文件的模式不以 * 结尾,则意味着您实际上希望匹配一个以此模式开头的配置文件列表(因此 */staging["*/staging", "*/staging,*"] 等的快捷方式)。这在例如您需要在本地运行“development”配置文件但又在远程运行“cloud”配置文件的情况下很常见。

每个仓库还可以选择将配置文件存储在子目录中,并且可以指定搜索这些目录的模式作为 search-paths。以下示例显示了顶层的一个配置文件:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          search-paths:
            - foo
            - bar*

在前面的示例中,服务器会在顶层、foo/ 子目录以及任何名称以 bar 开头的子目录中搜索配置文件。

默认情况下,当首次请求配置时,服务器会克隆远程仓库。服务器可以配置为在启动时克隆仓库,如以下顶层示例所示:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://git/common/config-repo.git
          repos:
            team-a:
                pattern: team-a-*
                cloneOnStart: true
                uri: https://git/team-a/config-repo.git
            team-b:
                pattern: team-b-*
                cloneOnStart: false
                uri: https://git/team-b/config-repo.git
            team-c:
                pattern: team-c-*
                uri: https://git/team-a/config-repo.git

在前面的示例中,服务器在启动时克隆 team-a 的配置仓库,然后才接受任何请求。所有其他仓库直到请求该仓库的配置时才会被克隆。

在 Config Server 启动时设置要克隆的仓库有助于在 Config Server 启动时快速识别配置错误的配置源(例如无效的仓库 URI)。如果未为配置源启用 cloneOnStart,Config Server 可能会成功启动并使用配置错误或无效的配置源,直到应用程序从该配置源请求配置时才检测到错误。
身份验证

要在远程仓库上使用 HTTP 基本身份验证,请单独添加 usernamepassword 属性(不要在 URL 中),如以下示例所示:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          username: trolley
          password: strongpassword

如果您不使用 HTTPS 和用户凭据,当您将密钥存储在默认目录 (~/.ssh) 中且 URI 指向 SSH 位置(例如 [email protected]:configuration/cloud-configuration)时,SSH 也应该开箱即用。重要的是,Git 服务器的条目必须存在于 ~/.ssh/known_hosts 文件中,并且必须采用 ssh-rsa 格式。其他格式(例如 ecdsa-sha2-nistp256)不受支持。为了避免意外,您应该确保 known_hosts 文件中只有一条 Git 服务器条目,并且它与您提供给配置服务器的 URL 匹配。如果您在 URL 中使用主机名,则需要在 known_hosts 文件中精确地拥有该主机名(而不是 IP)。仓库通过 JGit 访问,因此您找到的任何 JGit 文档都应该适用。HTTPS 代理设置可以在 ~/.git/config 中设置,或者(与任何其他 JVM 进程一样)通过系统属性(-Dhttps.proxyHost-Dhttps.proxyPort)设置。

如果您不知道 ~/.git 目录在哪里,请使用 git config --global 来操作设置(例如,git config --global http.sslVerify false)。

JGit 要求 RSA 密钥为 PEM 格式。以下是 ssh-keygen(来自 openssh)命令的一个示例,它将生成正确格式的密钥:

ssh-keygen -m PEM -t rsa -b 4096 -f ~/config_server_deploy_key.rsa

警告:使用 SSH 密钥时,预期的 SSH 私钥必须以 -----BEGIN RSA PRIVATE KEY----- 开头。如果密钥以 -----BEGIN OPENSSH PRIVATE KEY----- 开头,则在 Spring Cloud Config Server 启动时 RSA 密钥将无法加载。错误如下所示:

- Error in object 'spring.cloud.config.server.git': codes [PrivateKeyIsValid.spring.cloud.config.server.git,PrivateKeyIsValid]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [spring.cloud.config.server.git.,]; arguments []; default message []]; default message [Property 'spring.cloud.config.server.git.privateKey' is not a valid private key]

要纠正上述错误,RSA 密钥必须转换为 PEM 格式。上面提供了一个使用 openssh 的示例,用于生成正确格式的新密钥。

使用 AWS CodeCommit 进行身份验证

Spring Cloud Config Server 还支持 AWS CodeCommit 身份验证。AWS CodeCommit 在从命令行使用 Git 时使用身份验证助手。此助手不与 JGit 库一起使用,因此如果 Git URI 匹配 AWS CodeCommit 模式,则会为 AWS CodeCommit 创建 JGit CredentialProvider。AWS CodeCommit URI 遵循此模式:

https://git-codecommit.${AWS_REGION}.amazonaws.com/v1/repos/${repo}

如果您提供带有 AWS CodeCommit URI 的用户名和密码,则它们必须是提供对仓库访问权限的 AWS accessKeyId 和 secretAccessKey。如果您未指定用户名和密码,则会使用 Default Credential Provider Chain 检索 accessKeyId 和 secretAccessKey。

如果您的 Git URI 匹配 CodeCommit URI 模式(如前所示),您必须在用户名和密码中或在默认凭证提供程序链支持的位置之一提供有效的 AWS 凭证。AWS EC2 实例可以使用 EC2 实例的 IAM 角色

software.amazon.awssdk:auth jar 是一个可选依赖项。如果 software.amazon.awssdk:auth jar 不在您的类路径中,则不会创建 AWS Code Commit 凭证提供程序,无论 git 服务器 URI 如何。
使用 Google Cloud Source 进行身份验证

Spring Cloud Config Server 还支持针对 Google Cloud Source 仓库进行身份验证。

如果您的 Git URI 使用 httphttps 协议且域名是 source.developers.google.com,则将使用 Google Cloud Source 凭证提供程序。Google Cloud Source 仓库 URI 的格式为 https://source.developers.google.com/p/${GCP_PROJECT}/r/${REPO}。要获取仓库的 URI,请在 Google Cloud Source UI 中点击“克隆”,然后选择“手动生成的凭证”。不要生成任何凭证,只需复制显示的 URI 即可。

Google Cloud Source 凭据提供程序将使用 Google Cloud Platform 应用程序默认凭据。有关如何为系统创建应用程序默认凭据,请参阅 Google Cloud SDK 文档。此方法适用于开发环境中的用户帐户和生产环境中的服务帐户。

com.google.auth:google-auth-library-oauth2-http 是一个可选依赖项。如果 google-auth-library-oauth2-http jar 不在您的类路径中,则不会创建 Google Cloud Source 凭证提供程序,无论 git 服务器 URI 如何。
使用属性的 Git SSH 配置

默认情况下,Spring Cloud Config Server 使用的 JGit 库在通过 SSH URI 连接到 Git 仓库时会使用 SSH 配置文件,例如 ~/.ssh/known_hosts/etc/ssh/ssh_config。在 Cloud Foundry 等云环境中,本地文件系统可能是短暂的或不易访问的。对于这些情况,可以使用 Java 属性设置 SSH 配置。为了激活基于属性的 SSH 配置,必须将 spring.cloud.config.server.git.ignoreLocalSshSettings 属性设置为 true,如以下示例所示:

  spring:
    cloud:
      config:
        server:
          git:
            uri: [email protected]:team/repo1.git
            ignoreLocalSshSettings: true
            hostKey: someHostKey
            hostKeyAlgorithm: ssh-rsa
            privateKey: |
                         -----BEGIN RSA PRIVATE KEY-----
                         MIIEpgIBAAKCAQEAx4UbaDzY5xjW6hc9jwN0mX33XpTDVW9WqHp5AKaRbtAC3DqX
                         IXFMPgw3K45jxRb93f8tv9vL3rD9CUG1Gv4FM+o7ds7FRES5RTjv2RT/JVNJCoqF
                         ol8+ngLqRZCyBtQN7zYByWMRirPGoDUqdPYrj2yq+ObBBNhg5N+hOwKjjpzdj2Ud
                         1l7R+wxIqmJo1IYyy16xS8WsjyQuyC0lL456qkd5BDZ0Ag8j2X9H9D5220Ln7s9i
                         oezTipXipS7p7Jekf3Ywx6abJwOmB0rX79dV4qiNcGgzATnG1PkXxqt76VhcGa0W
                         DDVHEEYGbSQ6hIGSh0I7BQun0aLRZojfE3gqHQIDAQABAoIBAQCZmGrk8BK6tXCd
                         fY6yTiKxFzwb38IQP0ojIUWNrq0+9Xt+NsypviLHkXfXXCKKU4zUHeIGVRq5MN9b
                         BO56/RrcQHHOoJdUWuOV2qMqJvPUtC0CpGkD+valhfD75MxoXU7s3FK7yjxy3rsG
                         EmfA6tHV8/4a5umo5TqSd2YTm5B19AhRqiuUVI1wTB41DjULUGiMYrnYrhzQlVvj
                         5MjnKTlYu3V8PoYDfv1GmxPPh6vlpafXEeEYN8VB97e5x3DGHjZ5UrurAmTLTdO8
                         +AahyoKsIY612TkkQthJlt7FJAwnCGMgY6podzzvzICLFmmTXYiZ/28I4BX/mOSe
                         pZVnfRixAoGBAO6Uiwt40/PKs53mCEWngslSCsh9oGAaLTf/XdvMns5VmuyyAyKG
                         ti8Ol5wqBMi4GIUzjbgUvSUt+IowIrG3f5tN85wpjQ1UGVcpTnl5Qo9xaS1PFScQ
                         xrtWZ9eNj2TsIAMp/svJsyGG3OibxfnuAIpSXNQiJPwRlW3irzpGgVx/AoGBANYW
                         dnhshUcEHMJi3aXwR12OTDnaLoanVGLwLnkqLSYUZA7ZegpKq90UAuBdcEfgdpyi
                         PhKpeaeIiAaNnFo8m9aoTKr+7I6/uMTlwrVnfrsVTZv3orxjwQV20YIBCVRKD1uX
                         VhE0ozPZxwwKSPAFocpyWpGHGreGF1AIYBE9UBtjAoGBAI8bfPgJpyFyMiGBjO6z
                         FwlJc/xlFqDusrcHL7abW5qq0L4v3R+FrJw3ZYufzLTVcKfdj6GelwJJO+8wBm+R
                         gTKYJItEhT48duLIfTDyIpHGVm9+I1MGhh5zKuCqIhxIYr9jHloBB7kRm0rPvYY4
                         VAykcNgyDvtAVODP+4m6JvhjAoGBALbtTqErKN47V0+JJpapLnF0KxGrqeGIjIRV
                         cYA6V4WYGr7NeIfesecfOC356PyhgPfpcVyEztwlvwTKb3RzIT1TZN8fH4YBr6Ee
                         KTbTjefRFhVUjQqnucAvfGi29f+9oE3Ei9f7wA+H35ocF6JvTYUsHNMIO/3gZ38N
                         CPjyCMa9AoGBAMhsITNe3QcbsXAbdUR00dDsIFVROzyFJ2m40i4KCRM35bC/BIBs
                         q0TY3we+ERB40U8Z2BvU61QuwaunJ2+uGadHo58VSVdggqAo0BSkH58innKKt96J
                         69pcVH/4rmLbXdcmNYGm6iu+MlPQk4BUZknHSmVHIFdJ0EPupVaQ8RHT
                         -----END RSA PRIVATE KEY-----

下表描述了 SSH 配置属性。

表 1. SSH 配置属性
属性名称 备注

ignoreLocalSshSettings

如果为 true,则使用基于属性的 SSH 配置而不是基于文件的 SSH 配置。必须将其设置为 spring.cloud.config.server.git.ignoreLocalSshSettings,而不是在仓库定义内部。

privateKey

有效的 SSH 私钥。如果 ignoreLocalSshSettings 为 true 且 Git URI 为 SSH 格式,则必须设置。

hostKey

有效的 SSH 主机密钥。如果也设置了 hostKeyAlgorithm,则必须设置。

hostKeyAlgorithm

ssh-dss, ssh-rsa, ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, 或 ecdsa-sha2-nistp521 之一。如果也设置了 hostKey,则必须设置。

strictHostKeyChecking

truefalse。如果为 false,则忽略主机密钥错误。

knownHostsFile

自定义 .known_hosts 文件的位置。

preferredAuthentications

覆盖服务器身份验证方法顺序。如果服务器在 publickey 方法之前具有键盘交互式身份验证,则应允许避免登录提示。

Git 搜索路径中的占位符

Spring Cloud Config Server 还支持带有 {application}{profile}(如果需要,还有 {label})占位符的搜索路径,如以下示例所示:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          search-paths: '{application}'

上述列表会导致在仓库中搜索与目录同名的文件(以及顶层)。通配符在带有占位符的搜索路径中也有效(任何匹配的目录都包含在搜索中)。

Git 仓库中的强制拉取

如前所述,如果本地副本变脏(例如,文件夹内容因操作系统进程而更改),Spring Cloud Config Server 会克隆远程 git 仓库,这样 Spring Cloud Config Server 无法从远程仓库更新本地副本。

为了解决这个问题,有一个 force-pull 属性,它使 Spring Cloud Config Server 在本地副本脏时强制从远程仓库拉取,如以下示例所示:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          force-pull: true

如果您有多个仓库配置,您可以为每个仓库配置 force-pull 属性,如以下示例所示:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://git/common/config-repo.git
          force-pull: true
          repos:
            team-a:
                pattern: team-a-*
                uri: https://git/team-a/config-repo.git
                force-pull: true
            team-b:
                pattern: team-b-*
                uri: https://git/team-b/config-repo.git
                force-pull: true
            team-c:
                pattern: team-c-*
                uri: https://git/team-a/config-repo.git
force-pull 属性的默认值为 false
删除 Git 仓库中未跟踪的分支

由于 Spring Cloud Config Server 在将分支检出到本地仓库后(例如通过标签获取属性)会有一个远程 git 仓库的克隆,它将永远保留此分支,直到下一次服务器重新启动(这将创建新的本地仓库)。因此,可能会出现远程分支被删除但其本地副本仍可用于获取的情况。如果 Spring Cloud Config Server 客户端服务以 --spring.cloud.config.label=deletedRemoteBranch,master 启动,它将从 deletedRemoteBranch 本地分支获取属性,而不是从 master 获取。

为了保持本地仓库分支干净并与远程同步,可以设置 deleteUntrackedBranches 属性。它将使 Spring Cloud Config Server 强制从本地仓库删除未跟踪的分支。示例:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          deleteUntrackedBranches: true
deleteUntrackedBranches 属性的默认值为 false
Git 刷新率

您可以使用 spring.cloud.config.server.git.refreshRate 控制配置服务器从 Git 后端获取更新配置数据的频率。此属性的值以秒为单位指定。默认值为 0,这意味着配置服务器将在每次请求时从 Git 仓库获取更新的配置。

默认标签

Git 的默认标签是 main。如果您不设置 spring.cloud.config.server.git.defaultLabel 并且名为 main 的分支不存在,配置服务器将默认尝试检出名为 master 的分支。如果您想禁用回退分支行为,可以将 spring.cloud.config.server.git.tryMasterBranch 设置为 false

版本控制后端文件系统使用

对于基于 VCS 的后端(git、svn),文件会被检出或克隆到本地文件系统。默认情况下,它们会放在系统临时目录中,前缀为 config-repo-。例如,在 Linux 上,它可能是 /tmp/config-repo-<随机 ID>。某些操作系统会定期清理临时目录。这可能导致意外行为,例如属性丢失。为了避免此问题,通过设置 spring.cloud.config.server.git.basedirspring.cloud.config.server.svn.basedir 将 Config Server 使用的目录更改为不在系统临时结构中的目录。

文件系统后端

Config Server 中还有一个“native”配置文件,它不使用 Git,而是从本地类路径或文件系统加载配置文件(您可以指向 spring.cloud.config.server.native.searchLocations 的任何静态 URL)。要使用 native 配置文件,请使用 spring.profiles.active=native 启动 Config Server。

请记住,文件资源要使用 file: 前缀(没有前缀的默认值通常是类路径)。与任何 Spring Boot 配置一样,您可以嵌入 ${} 样式的环境占位符,但请记住,Windows 中的绝对路径需要额外的 /(例如,file:///${user.home}/config-repo)。
searchLocations 的默认值与本地 Spring Boot 应用程序相同(即 [classpath:/, classpath:/config, file:./, file:./config])。这不会将服务器的 application.properties 暴露给所有客户端,因为服务器中存在的任何属性源在发送到客户端之前都会被删除。
文件系统后端非常适合快速入门和测试。要在生产环境中使用它,您需要确保文件系统可靠且在 Config Server 的所有实例之间共享。

搜索位置可以包含 {application}{profile}{label} 的占位符。通过这种方式,您可以隔离路径中的目录,并选择适合您的策略(例如,每个应用程序一个子目录或每个配置文件一个子目录)。

如果您不在搜索位置中使用占位符,此仓库还会将 HTTP 资源的 {label} 参数附加到搜索路径的后缀,因此属性文件将从每个搜索位置与标签同名的子目录中加载(带标签的属性在 Spring Environment 中优先)。因此,没有占位符的默认行为与添加以 /{label}/ 结尾的搜索位置相同。例如,file:/tmp/configfile:/tmp/config,file:/tmp/config/{label} 相同。此行为可以通过设置 spring.cloud.config.server.native.addLabelLocations=false 来禁用。

Vault 后端

Spring Cloud Config Server 还支持 Vault 作为后端。

Vault 是一种安全访问秘密的工具。秘密是您希望严格控制访问的任何内容,例如 API 密钥、密码、证书和其他敏感信息。Vault 为任何秘密提供统一的接口,同时提供严格的访问控制并记录详细的审计日志。

有关 Vault 的更多信息,请参阅 Vault 快速入门指南

要使配置服务器使用 Vault 后端,您可以使用 vault 配置文件运行配置服务器。例如,在配置服务器的 application.properties 中,您可以添加 spring.profiles.active=vault

默认情况下,Spring Cloud Config Server 使用基于令牌的身份验证从 Vault 获取配置。Vault 还支持其他身份验证方法,如 AppRole、LDAP、JWT、CloudFoundry、Kubernetes Auth。为了使用 TOKEN 或 X-Config-Token 标头之外的任何身份验证方法,我们需要在类路径上拥有 Spring Vault Core,以便 Config Server 可以将身份验证委托给该库。请将以下依赖项添加到您的 Config Server 应用程序中。

Maven (pom.xml)

<dependencies>
	<dependency>
		<groupId>org.springframework.vault</groupId>
		<artifactId>spring-vault-core</artifactId>
	</dependency>
</dependencies>

Gradle (build.gradle)

dependencies {
    implementation "org.springframework.vault:spring-vault-core"
}

默认情况下,配置服务器假定您的 Vault 服务器运行在 http://127.0.0.1:8200。它还假定后端名称为 secret,键为 application。所有这些默认值都可以在配置服务器的 application.properties 中进行配置。下表描述了可配置的 Vault 属性:

名称 默认值

host

127.0.0.1

port

8200

scheme

http

backend

secret

defaultKey

application

profileSeparator

,

kvVersion

1

skipSslValidation

超时

5

namespace

null

上表中的所有属性都必须以 spring.cloud.config.server.vault 为前缀,或放置在复合配置的正确 Vault 部分中。

所有可配置属性都可以在 org.springframework.cloud.config.server.environment.VaultEnvironmentProperties 中找到。

Vault 0.10.0 引入了版本化的键值后端(k/v 后端版本 2),它公开了与早期版本不同的 API,现在需要在挂载路径和实际上下文路径之间有一个 data/,并将秘密包装在一个 data 对象中。设置 spring.cloud.config.server.vault.kv-version=2 将考虑这一点。

可选地,支持 Vault Enterprise X-Vault-Namespace 标头。要将其发送到 Vault,请设置 namespace 属性。

当您的配置服务器运行时,您可以向服务器发出 HTTP 请求以从 Vault 后端检索值。为此,您需要一个 Vault 服务器的令牌。

首先,在 Vault 中放置一些数据,如以下示例所示:

$ vault kv put secret/application foo=bar baz=bam
$ vault kv put secret/myapp foo=myappsbar

其次,向您的配置服务器发出 HTTP 请求以检索值,如以下示例所示:

$ curl -X "GET" "https://:8888/myapp/default" -H "X-Config-Token: yourtoken"

您应该看到类似于以下的响应:

{
   "name":"myapp",
   "profiles":[
      "default"
   ],
   "label":null,
   "version":null,
   "state":null,
   "propertySources":[
      {
         "name":"vault:myapp",
         "source":{
            "foo":"myappsbar"
         }
      },
      {
         "name":"vault:application",
         "source":{
            "baz":"bam",
            "foo":"bar"
         }
      }
   ]
}

客户端提供必要身份验证以使 Config Server 与 Vault 通信的默认方法是设置 X-Config-Token 标头。但是,您可以选择省略该标头,并通过设置与 Spring Cloud Vault 相同的配置属性来在服务器中配置身份验证。要设置的属性是 spring.cloud.config.server.vault.authentication。它应该设置为受支持的身份验证方法之一。您可能还需要通过使用与 spring.cloud.vault 文档中相同的属性名称但使用 spring.cloud.config.server.vault 前缀来设置您使用的身份验证方法特有的其他属性。有关详细信息,请参阅 Spring Cloud Vault 参考指南

如果您省略 X-Config-Token 标头并使用服务器属性设置身份验证,则 Config Server 应用程序需要额外依赖 Spring Vault 才能启用其他身份验证选项。有关如何添加该依赖项,请参阅 Spring Vault 参考指南
多个属性源

使用 Vault 时,您可以为应用程序提供多个属性源。例如,假设您已将数据写入 Vault 中的以下路径:

secret/myApp,dev
secret/myApp
secret/application,dev
secret/application

写入 secret/application 的属性可供所有使用配置服务器的应用程序使用。名为 myApp 的应用程序将可使用写入 secret/myAppsecret/application 的任何属性。当 myApp 启用了 dev 配置文件时,上述所有路径中写入的属性都将可用,其中列表中第一个路径中的属性优先于其他属性。

通过代理访问后端

配置服务器可以通过 HTTP 或 HTTPS 代理访问 Git 或 Vault 后端。此行为由 proxy.httpproxy.https 下的设置控制,适用于 Git 或 Vault。这些设置是每个仓库的,因此如果使用复合环境仓库,则必须为复合中的每个后端单独配置代理设置。如果使用需要独立的 HTTP 和 HTTPS URL 代理服务器的网络,则可以为单个后端同时配置 HTTP 和 HTTPS 代理设置:在这种情况下,http 访问将使用 http 代理,https 访问将使用 https 代理。此外,您可以指定一个唯一的代理,该代理将用于应用程序和代理之间的两种协议,使用代理定义协议。

下表描述了 HTTP 和 HTTPS 代理的代理配置属性。所有这些属性都必须以 proxy.httpproxy.https 为前缀。

表 2. 代理配置属性
属性名称 备注

host

代理的主机。

port

访问代理的端口。

nonProxyHosts

配置服务器应在代理之外访问的任何主机。如果同时提供了 proxy.http.nonProxyHostsproxy.https.nonProxyHosts 的值,则将使用 proxy.http 的值。

username

用于向代理进行身份验证的用户名。如果同时提供了 proxy.http.usernameproxy.https.username 的值,则将使用 proxy.http 的值。

password

用于向代理进行身份验证的密码。如果同时提供了 proxy.http.passwordproxy.https.password 的值,则将使用 proxy.http 的值。

以下配置使用 HTTPS 代理访问 Git 仓库。

spring:
  profiles:
    active: git
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          proxy:
            https:
              host: my-proxy.host.io
              password: myproxypassword
              port: '3128'
              username: myproxyusername
              nonProxyHosts: example.com

与所有应用程序共享配置

与所有应用程序共享配置因您采用的方法而异,如以下主题所述:

基于文件的仓库

对于基于文件(git、svn 和 native)的仓库,文件名为 application*application.propertiesapplication.ymlapplication-*.properties 等)的资源在所有客户端应用程序之间共享。您可以使用这些文件名的资源来配置全局默认值,并在必要时由特定于应用程序的文件覆盖它们。

属性覆盖功能也可用于设置全局默认值,允许占位符应用程序在本地覆盖它们。

对于“native”配置文件(本地文件系统后端),您应该使用一个明确的搜索位置,该位置不属于服务器自己的配置。否则,默认搜索位置中的 application* 资源将被删除,因为它们是服务器的一部分。
Vault 服务器

当使用 Vault 作为后端时,您可以通过将配置放置在 secret/application 中来与所有应用程序共享配置。例如,如果您运行以下 Vault 命令,所有使用配置服务器的应用程序都将可使用属性 foobaz

$ vault write secret/application foo=bar baz=bam
CredHub 服务器

当使用 CredHub 作为后端时,您可以通过将配置放置在 /application/ 中或将其放置在应用程序的 default 配置文件中来与所有应用程序共享配置。例如,如果您运行以下 CredHub 命令,所有使用配置服务器的应用程序都将可使用属性 shared.color1shared.color2

credhub set --name "/application/profile/master/shared" --type=json
value: {"shared.color1": "blue", "shared.color": "red"}
credhub set --name "/my-app/default/master/more-shared" --type=json
value: {"shared.word1": "hello", "shared.word2": "world"}

AWS Secrets Manager

当使用 AWS Secrets Manager 作为后端时,您可以通过将配置放置在 /application/ 中或将其放置在应用程序的 default 配置文件中来与所有应用程序共享配置。例如,如果您添加具有以下键的秘密,所有使用配置服务器的应用程序都将可使用属性 shared.fooshared.bar

secret name = /secret/application-default/
secret value =
{
 shared.foo: foo,
 shared.bar: bar
}

secret name = /secret/application/
secret value =
{
 shared.foo: foo,
 shared.bar: bar
}
带标签的版本

AWS Secrets Manager 仓库允许以与 Git 后端相同的方式保留配置环境的带标签版本。

仓库实现将 HTTP 资源的 {label} 参数映射到 AWS Secrets Manager 秘密的暂存标签。要创建带标签的秘密,请创建秘密或更新其内容并为其定义一个暂存标签(有时在 AWS 文档中称为版本阶段)。例如:

$ aws secretsmanager create-secret \
      --name /secret/test/ \
      --secret-string '{"version":"1"}'
{
    "ARN": "arn:aws:secretsmanager:us-east-1:123456789012:secret:/secret/test/-a1b2c3",
    "Name": "/secret/test/",
    "VersionId": "cd291674-de2f-41de-8f3b-37dbf4880d69"
}

$ aws secretsmanager update-secret-version-stage \
      --secret-id /secret/test/ \
      --version-stage 1.0.0 \
      --move-to-version-id cd291674-de2f-41de-8f3b-37dbf4880d69

{
    "ARN": "arn:aws:secretsmanager:us-east-1:123456789012:secret:/secret/test/-a1b2c3",
    "Name": "/secret/test/",
}

使用 spring.cloud.config.server.aws-secretsmanager.default-label 属性设置默认标签。如果未定义该属性,后端将使用 AWSCURRENT 作为暂存标签。

spring:
  profiles:
    active: aws-secretsmanager
  cloud:
    config:
      server:
        aws-secretsmanager:
          region: us-east-1
          default-label: 1.0.0

请注意,如果未设置默认标签且请求未定义标签,则仓库将使用秘密,就好像已禁用带标签版本支持一样。此外,默认标签仅在启用带标签支持时才使用。否则,定义此属性毫无意义。

请注意,如果暂存标签包含斜杠 (/),则 HTTP URL 中的标签应改为使用特殊字符串 (_) 指定(以避免与其他 URL 路径混淆),与 Git 后端部分中描述的方式相同。

使用 spring.cloud.config.server.aws-secretsmanager.ignore-label 属性可忽略 HTTP 资源的 {label} 参数以及 spring.cloud.config.server.aws-secretsmanager.default-label 属性。仓库将使用秘密,就好像已禁用带标签版本支持一样。

spring:
  profiles:
    active: aws-secretsmanager
  cloud:
    config:
      server:
        aws-secretsmanager:
          region: us-east-1
          ignore-label: true

AWS Parameter Store

当使用 AWS Parameter Store 作为后端时,您可以通过将属性放置在 /application 层次结构中来与所有应用程序共享配置。

例如,如果您添加具有以下名称的参数,所有使用配置服务器的应用程序都将可使用属性 foo.barfred.baz

/config/application/foo.bar
/config/application-default/fred.baz

JDBC 后端

Spring Cloud Config Server 支持 JDBC(关系数据库)作为配置属性的后端。您可以通过将 spring-boot-starter-data-jdbc 添加到类路径并使用 jdbc 配置文件,或者通过添加类型为 JdbcEnvironmentRepository 的 bean 来启用此功能。如果您在类路径中包含正确的依赖项(有关详细信息,请参阅用户指南),Spring Boot 将配置一个数据源。

您可以通过将 spring.cloud.config.server.jdbc.enabled 属性设置为 false 来禁用 JdbcEnvironmentRepository 的自动配置。

数据库需要有一个名为 PROPERTIES 的表,其中包含名为 APPLICATIONPROFILELABEL 的列(具有通常的 Environment 含义),以及用于 Properties 样式键值对的 KEYVALUE 列。所有字段在 Java 中都为 String 类型,因此您可以根据需要将其设置为任意长度的 VARCHAR。属性值的行为方式与来自名为 {application}-{profile}.properties 的 Spring Boot 属性文件时的行为方式相同,包括所有加密和解密,这些都将作为后处理步骤应用(即,不直接在仓库实现中)。

JDBC 的默认标签是 master。您可以通过设置 spring.cloud.config.server.jdbc.defaultLabel 来更改它。

Redis 后端

Spring Cloud Config Server 支持 Redis 作为配置属性的后端。您可以通过添加对 Spring Data Redis 的依赖来启用此功能。

pom.xml
<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-data-redis</artifactId>
	</dependency>
</dependencies>

以下配置使用 Spring Data RedisTemplate 访问 Redis。我们可以使用 spring.redis.* 属性覆盖默认连接设置。

spring:
  profiles:
    active: redis
  redis:
    host: redis
    port: 16379

这些属性应以字段形式存储在哈希中。哈希的名称应与 spring.application.name 属性或 spring.application.namespring.profiles.active[n] 的组合相同。

HMSET sample-app server.port "8100" sample.topic.name "test" test.property1 "property1"

运行上述命令后,哈希应包含以下键值对:

HGETALL sample-app
{
  "server.port": "8100",
  "sample.topic.name": "test",
  "test.property1": "property1"
}
未指定配置文件时,将使用 default

AWS S3 后端

Spring Cloud Config Server 支持 AWS S3 作为配置属性的后端。您可以通过添加对 AWS Java SDK For Amazon S3 的依赖来启用此功能。

pom.xml
<dependencies>
	<dependency>
		<groupId>software.amazon.awssdk</groupId>
		<artifactId>s3</artifactId>
	</dependency>
</dependencies>

以下配置使用 AWS S3 客户端访问配置文件。我们可以使用 spring.cloud.config.server.awss3.* 属性来选择存储配置的存储桶。

spring:
  profiles:
    active: awss3
  cloud:
    config:
      server:
        awss3:
          region: us-east-1
          bucket: bucket1

还可以指定一个 AWS URL 来使用 spring.cloud.config.server.awss3.endpoint 覆盖 S3 服务的标准端点。这允许支持 S3 的测试版区域和其他 S3 兼容的存储 API。

凭据使用 默认凭据提供程序链 查找。版本化和加密的存储桶无需进一步配置即可支持。

配置文件以 {application}-{profile}.properties{application}-{profile}.yml{application}-{profile}.json 形式存储在您的存储桶中。可以提供可选标签以指定文件的目录路径。

未指定配置文件时,将使用 default

AWS Parameter Store 后端

Spring Cloud Config Server 支持 AWS Parameter Store 作为配置属性的后端。您可以通过添加对 AWS Java SDK for SSM 的依赖来启用此功能。

pom.xml
<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>ssm</artifactId>
</dependency>

以下配置使用 AWS SSM 客户端访问参数。

spring:
  profiles:
    active: awsparamstore
  cloud:
    config:
      server:
        awsparamstore:
          region: eu-west-2
          endpoint: https://ssm.eu-west-2.amazonaws.com
          origin: aws:parameter:
          prefix: /config/service
          profile-separator: _
          recursive: true
          decrypt-values: true
          max-results: 5

下表描述了 AWS Parameter Store 配置属性。

表 3. AWS Parameter Store 配置属性
属性名称 必需 默认值 备注

region

no

AWS Parameter Store 客户端将使用的区域。如果未明确设置,SDK 将尝试使用 默认区域提供程序链 来确定要使用的区域。

endpoint

no

AWS SSM 客户端入口点的 URL。这可用于为 API 请求指定备用端点。

origin

no

aws:ssm:parameter

添加到属性源名称的前缀,以显示其来源。

prefix

no

/config

表示从 AWS Parameter Store 加载的每个属性在参数层次结构中的 L1 级别的​​前缀。

profile-separator

no

-

分隔附加配置文件与上下文名称的字符串。

recursive

no

true

指示检索层次结构中所有 AWS 参数的标志。

decrypt-values

no

true

指示检索所有 AWS 参数并解密其值的标志。

max-results

no

10

AWS Parameter Store API 调用返回的最大项目数。

AWS Parameter Store API 凭证使用 默认凭证提供程序链 确定。版本化参数已经通过返回最新版本的默认行为得到支持。

  • 当未指定应用程序时,默认使用 application;当未指定配置文件时,默认使用 default

  • awsparamstore.prefix 的有效值必须以正斜杠开头,后跟一个或多个有效路径段,或者为空。

  • awsparamstore.profile-separator 的有效值只能包含点、短划线和下划线。

  • awsparamstore.max-results 的有效值必须在 [1, 10] 范围内。

AWS Secrets Manager 后端

Spring Cloud Config Server 支持 AWS Secrets Manager 作为配置属性的后端。您可以通过添加对 AWS Java SDK for Secrets Manager 的依赖来启用此功能。

pom.xml
<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>secretsmanager</artifactId>
</dependency>

以下配置使用 AWS Secrets Manager 客户端访问秘密。

spring:
  profiles:
  	active: awssecretsmanager
  cloud:
    config:
      server:
        aws-secretsmanager:
          region: us-east-1
          endpoint: https://us-east-1.console.aws.amazon.com/
          origin: aws:secrets:
          prefix: /secret/foo
          profileSeparator: _

AWS Secrets Manager API 凭据使用 默认凭据提供程序链 确定。

  • 当未指定应用程序时,默认使用 application;当未指定配置文件时,默认使用 default

  • ignoreLabel 设置为 true 时,labeldefaultLabel 属性都将被忽略。

CredHub 后端

Spring Cloud Config Server 支持 CredHub 作为配置属性的后端。您可以通过添加对 Spring CredHub 的依赖来启用此功能。

pom.xml
<dependencies>
	<dependency>
		<groupId>org.springframework.credhub</groupId>
		<artifactId>spring-credhub-starter</artifactId>
	</dependency>
</dependencies>

以下配置使用相互 TLS 访问 CredHub:

spring:
  profiles:
    active: credhub
  cloud:
    config:
      server:
        credhub:
          url: https://credhub:8844

属性应以 JSON 格式存储,例如:

credhub set --name "/demo-app/default/master/toggles" --type=json
value: {"toggle.button": "blue", "toggle.link": "red"}
credhub set --name "/demo-app/default/master/abs" --type=json
value: {"marketing.enabled": true, "external.enabled": false}

所有名为 spring.cloud.config.name=demo-app 的客户端应用程序都将拥有以下属性:

{
    toggle.button: "blue",
    toggle.link: "red",
    marketing.enabled: true,
    external.enabled: false
}
未指定 profile 时将使用 default,未指定 label 时将使用 master 作为默认值。注意:添加到 application 的值将由所有应用程序共享。
OAuth 2.0

您可以使用 OAuth 2.0 并以 UAA 作为提供商进行身份验证。

pom.xml
<dependencies>
	<dependency>
		<groupId>org.springframework.security</groupId>
		<artifactId>spring-security-config</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.security</groupId>
		<artifactId>spring-security-oauth2-client</artifactId>
	</dependency>
</dependencies>

以下配置使用 OAuth 2.0 和 UAA 访问 CredHub:

spring:
  profiles:
    active: credhub
  cloud:
    config:
      server:
        credhub:
          url: https://credhub:8844
          oauth2:
            registration-id: credhub-client
  security:
    oauth2:
      client:
        registration:
          credhub-client:
            provider: uaa
            client-id: credhub_config_server
            client-secret: asecret
            authorization-grant-type: client_credentials
        provider:
          uaa:
            token-uri: https://uaa:8443/oauth/token
使用的 UAA 客户端 ID 应具有 credhub.read 范围。

复合环境仓库

在某些情况下,您可能希望从多个环境仓库中拉取配置数据。为此,您可以在配置服务器的应用程序属性或 YAML 文件中启用 composite 配置文件。例如,如果您想从 Subversion 仓库以及两个 Git 仓库中拉取配置数据,您可以为配置服务器设置以下属性:

spring:
  profiles:
    active: composite
  cloud:
    config:
      server:
        composite:
        -
          type: svn
          uri: file:///path/to/svn/repo
        -
          type: git
          uri: file:///path/to/rex/git/repo
        -
          type: git
          uri: file:///path/to/walter/git/repo

使用此配置,优先级由 composite 键下仓库的列出顺序决定。在上面的示例中,Subversion 仓库排在第一位,因此在 Subversion 仓库中找到的值将覆盖在其中一个 Git 仓库中找到的相同属性的值。在 rex Git 仓库中找到的值将优先于在 walter Git 仓库中找到的相同属性的值。

如果您只想从不同类型的仓库中拉取配置数据,您可以在配置服务器的应用程序属性或 YAML 文件中启用相应的配置文件,而不是 composite 配置文件。例如,如果您想从单个 Git 仓库和单个 HashiCorp Vault 服务器中拉取配置数据,您可以为配置服务器设置以下属性:

spring:
  profiles:
    active: git, vault
  cloud:
    config:
      server:
        git:
          uri: file:///path/to/git/repo
          order: 2
        vault:
          host: 127.0.0.1
          port: 8200
          order: 1

使用此配置,优先级可以通过 order 属性确定。您可以使用 order 属性指定所有仓库的优先级顺序。order 属性的数值越低,其优先级越高。仓库的优先级顺序有助于解决包含相同属性值的仓库之间任何潜在的冲突。

如果您的复合环境包含 Vault 服务器,如前一个示例所示,您必须在向配置服务器发出的每个请求中包含 Vault 令牌。请参阅 Vault 后端
从环境仓库检索值时出现的任何类型的故障都会导致整个复合环境的故障。如果您希望复合环境在仓库失败时仍能继续运行,您可以将 spring.cloud.config.server.failOnCompositeError 设置为 false
使用复合环境时,所有仓库包含相同的标签非常重要。如果您有一个类似于前面示例的环境,并且您使用 master 标签请求配置数据,但 Subversion 仓库不包含名为 master 的分支,则整个请求将失败。
自定义复合环境仓库

除了使用 Spring Cloud 中的一个环境仓库之外,您还可以提供自己的 EnvironmentRepository bean 作为复合环境的一部分。为此,您的 bean 必须实现 EnvironmentRepository 接口。如果您想控制自定义 EnvironmentRepository 在复合环境中的优先级,您还应该实现 Ordered 接口并重写 getOrdered 方法。如果您不实现 Ordered 接口,您的 EnvironmentRepository 将获得最低优先级。

属性覆盖

Config Server 具有“覆盖”功能,允许操作员向所有应用程序提供配置属性。通过正常的 Spring Boot 钩子,应用程序无法意外更改这些被覆盖的属性。要声明覆盖,请将名称-值对映射添加到 spring.cloud.config.server.overrides,如以下示例所示:

spring:
  cloud:
    config:
      server:
        overrides:
          foo: bar

前面的示例使得所有作为配置客户端的应用程序都读取 foo=bar,而不管它们自己的配置如何。

配置系统无法强制应用程序以任何特定方式使用配置数据。因此,覆盖是不可强制执行的。但是,它们确实为 Spring Cloud Config 客户端提供了有用的默认行为。
通常,带有 ${} 的 Spring 环境占位符可以通过使用反斜杠 (\) 转义 ${ 来转义(并在客户端解析)。例如,\${app.foo:bar} 解析为 bar,除非应用程序提供了自己的 app.foo
在 YAML 中,您不需要转义反斜杠本身。但是,在属性文件中,当您在服务器上配置覆盖时,确实需要转义反斜杠。

您可以通过在远程仓库中设置 spring.cloud.config.overrideNone=true 标志(默认值为 false),将客户端中所有覆盖的优先级更改为更像默认值,允许应用程序在环境变量或系统属性中提供自己的值。

使用 Bootstrap 覆盖属性

如果启用配置优先启动,您可以通过在客户端应用程序配置中放置两个属性(这些属性位于配置服务器使用的外部环境仓库(例如 Git、Vault、SVN 等)中)来让客户端设置覆盖来自配置服务器的配置。

spring.cloud.config.allowOverride=true
spring.cloud.config.overrideNone=true

如果启用了 Bootstrap 并且这两个属性都设置为 true,您将能够从客户端应用程序配置中覆盖来自配置服务器的配置。

使用占位符覆盖属性

一种更简洁的覆盖属性方式,无需启用配置优先引导,是在来自配置服务器的配置中使用属性占位符。

例如,如果来自配置服务器的配置包含以下属性:

hello=${app.hello:Hello From Config Server!}

您可以通过在本地应用程序配置中设置 app.hello 来覆盖来自配置服务器的 hello 值:

app.hello=Hello From Application!

使用配置文件覆盖属性

覆盖来自配置服务器属性的最后一种方法是在客户端应用程序内部的特定于配置文件的配置文件中指定它们。

例如,如果您的配置服务器有以下配置:

hello="Hello From Config Server!"

您可以通过在特定于配置文件的配置文件中设置 hello,然后启用该配置文件来覆盖客户端应用程序中的 hello 值。

application-overrides.properties
hello="Hello From Application!"

在上面的例子中,您必须启用 overrides 配置文件。

健康指示器

Config Server 配备了一个健康指示器,用于检查配置的 EnvironmentRepository 是否正常工作。默认情况下,它会向 EnvironmentRepository 请求一个名为 app 的应用程序、default 配置文件以及 EnvironmentRepository 实现提供的默认标签。

您可以配置健康指示器,以检查更多应用程序以及自定义配置文件和自定义标签,如以下示例所示:

spring:
  cloud:
    config:
      server:
        health:
          repositories:
            myservice:
              label: mylabel
            myservice-dev:
              name: myservice
              profiles: development

您可以通过设置 management.health.config.enabled=false 来禁用健康指示器。

此外,您可以通过设置属性 spring.cloud.config.server.health.down-health-status(默认为 "DOWN')来提供自定义的 down 状态。

安全性

您可以以任何对您有意义的方式保护您的 Config Server(从物理网络安全到 OAuth2 bearer token),因为 Spring Security 和 Spring Boot 支持许多安全安排。

要使用默认的 Spring Boot 配置的 HTTP 基本安全,请在类路径中包含 Spring Security(例如,通过 spring-boot-starter-security)。默认用户名是 user,密码是随机生成的。随机密码在实践中没有用,因此我们建议您配置密码(通过设置 spring.security.user.password)并对其进行加密(请参阅下文了解操作说明)。

Actuator 和安全性

某些平台会配置健康检查或类似的东西,并指向 /actuator/health 或其他 Actuator 端点。如果 Actuator 不是配置服务器的依赖项,则对 /actuator/** 的请求将匹配配置服务器 API /{application}/{label},可能泄露安全信息。在这种情况下,请记住添加 spring-boot-starter-actuator 依赖项,并配置用户,使调用 /actuator/** 的用户无权访问 /{application}/{label} 处的配置服务器 API。

加密和解密

要使用加密和解密功能,您需要在 JVM 中安装完整强度的 JCE(默认不包含)。您可以从 Oracle 下载“Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files”,并按照安装说明进行操作(基本上,您需要将 JRE lib/security 目录中的两个策略文件替换为您下载的文件)。

如果远程属性源包含加密内容(以 {cipher} 开头的值),则在通过 HTTP 发送给客户端之前对其进行解密。此设置的主要优点是,属性值在“静止”时(例如,在 git 仓库中)不需要是明文。如果值无法解密,则会从属性源中删除该值,并添加一个具有相同键但前缀为 invalid 且值为“不适用”(通常为 <n/a>)的附加属性。这主要是为了防止密文被用作密码并意外泄露。

如果您为配置客户端应用程序设置了远程配置仓库,它可能包含一个类似于以下的 application.yml

application.yml
spring:
  datasource:
    username: dbuser
    password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ'

application.properties 文件中的加密值不能用引号括起来。否则,该值将不会被解密。以下示例显示了将起作用的值:

application.properties
spring.datasource.username: dbuser
spring.datasource.password: {cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ

您可以安全地将此明文推送到共享的 git 仓库,并且秘密密码仍然受到保护。

服务器还公开了 /encrypt/decrypt 端点(假设这些端点是安全的,并且只有经过授权的代理才能访问)。如果您编辑远程配置文件,您可以使用 Config Server 通过 POST 请求到 /encrypt 端点来加密值,如以下示例所示:

$ curl localhost:8888/encrypt -s -d mysecret
682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
如果您正在使用 curl 进行测试,请使用 --data-urlencode(而不是 -d),并在要加密的值前面加上 =(curl 需要这样做),或者设置明确的 Content-Type: text/plain 以确保 curl 在存在特殊字符(特别是“+”很麻烦)时正确编码数据。
请确保不要在加密值中包含任何 curl 命令统计信息,这就是为什么示例中使用 -s 选项来禁用它们的原因。将值输出到文件有助于避免此问题。

逆操作也可以通过 /decrypt 进行(前提是服务器配置了对称密钥或完整的密钥对),如以下示例所示:

$ curl localhost:8888/decrypt -s -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
mysecret

获取加密值,并在将其放入 YAML 或属性文件之前,以及在将其提交并推送到远程(可能不安全)存储之前,添加 {cipher} 前缀。

/encrypt/decrypt 端点都接受 /*/{application}/{profiles} 形式的路径,当客户端调用主环境资源时,这可用于按应用程序(名称)和按配置文件控制加密。

要以这种精细的方式控制加密,您还必须提供一个 TextEncryptorLocator 类型的 @Bean,它为每个名称和配置文件创建不同的加密器。默认提供的加密器不这样做(所有加密都使用相同的密钥)。

spring 命令行客户端(安装了 Spring Cloud CLI 扩展)也可用于加密和解密,如以下示例所示:

$ spring encrypt mysecret --key foo
682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
$ spring decrypt --key foo 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
mysecret

要在文件中使用密钥(例如用于加密的 RSA 公钥),请在密钥值前面加上“@”并提供文件路径,如以下示例所示:

$ spring encrypt mysecret --key @${HOME}/.ssh/id_rsa.pub
AQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+...
--key 参数是强制性的(尽管有 -- 前缀)。

密钥管理

Config Server 可以使用对称(共享)密钥或非对称密钥(RSA 密钥对)。非对称密钥在安全性方面更优越,但使用对称密钥通常更方便,因为它是在 application.properties 中配置的单个属性值。

要配置对称密钥,您需要将 encrypt.key 设置为一个秘密字符串(或使用 ENCRYPT_KEY 环境变量以避免将其保留在纯文本配置文件中)。

如果在类路径中包含 spring-cloud-starter-bootstrap 或将 spring.cloud.bootstrap.enabled=true 设置为系统属性,则需要在 bootstrap.properties 中设置 encrypt.key
您不能使用 encrypt.key 配置非对称密钥。

要配置非对称密钥,请使用密钥库(例如,由 JDK 附带的 keytool 工具创建)。密钥库属性是 encrypt.keyStore.*,其中 * 等于:

财产 描述

encrypt.keyStore.location

包含一个 Resource 位置

encrypt.keyStore.password

保存解锁密钥库的密码

encrypt.keyStore.alias

标识要使用的密钥库中的密钥

encrypt.keyStore.type

要创建的 KeyStore 类型。默认为 jks

加密使用公钥完成,解密需要私钥。因此,原则上,如果您只想加密(并准备好使用私钥在本地解密值),则可以在服务器中仅配置公钥。实际上,您可能不想在本地解密,因为它会将密钥管理过程分散到所有客户端,而不是将其集中在服务器中。另一方面,如果您的配置服务器相对不安全,并且只有少数客户端需要加密属性,那么它可能是一个有用的选项。

创建用于测试的密钥库

要创建用于测试的密钥库,您可以使用类似于以下内容的命令:

$ keytool -genkeypair -alias mytestkey -keyalg RSA \
  -dname "CN=Web Server,OU=Unit,O=Organization,L=City,S=State,C=US" \
  -keypass changeme -keystore server.jks -storepass letmein
当使用 JDK 11 或更高版本时,使用上述命令可能会收到以下警告。在这种情况下,您可能需要确保 keypassstorepass 值匹配。
Warning:  Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified -keypass value.

server.jks 文件放入类路径(例如),然后,在 Config Server 的 bootstrap.yml 中,创建以下设置:

encrypt:
  keyStore:
    location: classpath:/server.jks
    password: letmein
    alias: mytestkey
    secret: changeme

使用多个密钥和密钥轮换

除了加密属性值中的 {cipher} 前缀之外,Config Server 还在(Base64 编码的)密文开头查找零个或多个 {name:value} 前缀。密钥被传递给 TextEncryptorLocator,它可以执行任何所需的逻辑来为密文定位 TextEncryptor。如果您已配置密钥库(encrypt.keystore.location),则默认定位器会查找由 key 前缀提供的别名密钥,其密文类似于以下内容:

foo:
  bar: `{cipher}{key:testkey}...`

定位器查找名为“testkey”的密钥。还可以通过在前缀中使用 {secret:…​} 值来提供秘密。但是,如果未提供,默认是使用密钥库密码(这是您构建密钥库且未指定秘密时获得的结果)。如果您确实提供了秘密,则还应该使用自定义 SecretLocator 加密秘密。

当密钥仅用于加密少量配置数据(即,它们未在其他地方使用)时,从密码学角度来看,密钥轮换几乎没有必要。但是,您可能偶尔需要更改密钥(例如,发生安全漏洞时)。在这种情况下,所有客户端都需要更改其源配置文件(例如,在 git 中),并在所有密文中使用新的 {key:…​} 前缀。请注意,客户端需要首先检查密钥别名是否在 Config Server 密钥库中可用。

如果您希望 Config Server 处理所有加密和解密,{name:value} 前缀也可以作为纯文本发布到 /encrypt 端点。

提供加密属性

有时您希望客户端在本地解密配置,而不是在服务器中进行。在这种情况下,如果您提供 encrypt.* 配置以定位密钥,您仍然可以拥有 /encrypt/decrypt 端点,但您需要通过在 bootstrap.[yml|properties] 中放置 spring.cloud.config.server.encrypt.enabled=false 来显式关闭出站属性的解密。如果您不关心端点,那么如果您既不配置密钥也不配置启用标志,它应该可以工作。

提供替代格式

环境端点的默认 JSON 格式非常适合 Spring 应用程序使用,因为它直接映射到 Environment 抽象。如果您愿意,可以通过在资源路径中添加后缀(“.yml”、“.yaml”或“.properties”)来将相同数据作为 YAML 或 Java 属性使用。这对于不关心 JSON 端点结构或其提供额外元数据的应用程序可能很有用(例如,不使用 Spring 的应用程序可能会受益于这种方法的简单性)。

YAML 和属性表示具有一个附加标志(作为名为 resolvePlaceholders 的布尔查询参数提供),用于指示在呈现之前,源文档中的占位符(以标准 Spring ${…​} 形式)应在输出中解析,如果可能的话。这对于不了解 Spring 占位符约定的消费者来说是一个有用的功能。

使用 YAML 或属性格式存在局限性,主要与元数据丢失有关。例如,JSON 被构造成一个有序的属性源列表,其名称与源相关联。YAML 和属性形式被合并为一个单一的映射,即使值的来源有多个源,并且原始源文件的名称也丢失了。此外,YAML 表示也不一定是后端仓库中 YAML 源的忠实表示。它是从一个平面属性源列表构建的,并且必须对键的形式进行假设。

提供纯文本

您的应用程序可能需要适合其环境的通用纯文本配置文件,而不是使用 Environment 抽象(或其在 YAML 或属性格式中的替代表示之一)。Config Server 通过 /{application}/{profile}/{label}/{path} 处的附加端点提供这些文件,其中 applicationprofilelabel 具有与常规环境端点相同的含义,但 path 是文件名的路径(例如 log.xml)。此端点的源文件与环境端点的文件以相同的方式定位。属性文件和 YAML 文件使用相同的搜索路径。但是,不是聚合所有匹配的资源,而是仅返回第一个匹配的资源。

定位资源后,使用提供的应用程序名称、配置文件和标签的有效 Environment 解析正常格式(${…​})中的占位符。通过这种方式,资源端点与环境端点紧密集成。

与环境配置的源文件一样,profile 用于解析文件名。因此,如果您想要一个特定于配置文件的文件,/*/development/*/logback.xml 可以通过名为 logback-development.xml 的文件(优先于 logback.xml)进行解析。
如果您不想提供 label 并让服务器使用默认标签,您可以提供 useDefaultLabel 请求参数。因此,default 配置文件的上述示例可以是 /sample/default/nginx.conf?useDefaultLabel

目前,Spring Cloud Config 可以为 git、SVN、本地后端和 AWS S3 提供纯文本。对 git、SVN 和本地后端的支持是相同的。AWS S3 的工作方式略有不同。以下部分展示了它们的工作方式:

提供二进制文件

为了从配置服务器提供二进制文件,您需要发送一个 Accept 标头,其值为 application/octet-stream

Git、SVN 和原生后端

考虑以下针对 GIT 或 SVN 仓库或原生后端的示例:

application.yml
nginx.conf

nginx.conf 可能类似于以下列表:

server {
    listen              80;
    server_name         ${nginx.server.name};
}

application.yml 可能类似于以下列表:

nginx:
  server:
    name: example.com
---
spring:
  profiles: development
nginx:
  server:
    name: develop.com

/sample/default/master/nginx.conf 资源可能如下所示:

server {
    listen              80;
    server_name         example.com;
}

/sample/development/master/nginx.conf 可能如下所示:

server {
    listen              80;
    server_name         develop.com;
}

AWS S3

为了支持 AWS S3 的纯文本服务,Config Server 应用程序需要包含对 io.awspring.cloud:spring-cloud-aws-context 的依赖。有关如何设置该依赖项的详细信息,请参阅 Spring Cloud AWS 参考指南。此外,在使用 Spring Cloud AWS 和 Spring Boot 时,包含 自动配置依赖项 会很有用。然后,您需要配置 Spring Cloud AWS,如 Spring Cloud AWS 参考指南 中所述。

解密纯文本

默认情况下,纯文本文件中的加密值不会被解密。为了启用纯文本文件的解密,请在 bootstrap.[yml|properties] 中设置 spring.cloud.config.server.encrypt.enabled=truespring.cloud.config.server.encrypt.plainTextEncrypt=true

解密纯文本文件仅支持 YAML、JSON 和属性文件扩展名。

如果启用此功能并请求不受支持的文件扩展名,则文件中的任何加密值都不会被解密。

嵌入 Config Server

Config Server 最好作为独立应用程序运行。但是,如果需要,您可以将其嵌入到另一个应用程序中。为此,请使用 @EnableConfigServer 注解。在这种情况下,一个名为 spring.cloud.config.server.bootstrap 的可选属性可能很有用。它是一个标志,指示服务器是否应该从自己的远程仓库配置自己。默认情况下,该标志是关闭的,因为它可能会延迟启动。但是,当嵌入到另一个应用程序中时,以与其他应用程序相同的方式初始化是有意义的。当将 spring.cloud.config.server.bootstrap 设置为 true 时,您还必须使用复合环境仓库配置。例如:

spring:
  application:
    name: configserver
  profiles:
    active: composite
  cloud:
    config:
      server:
        composite:
          - type: native
            search-locations: ${HOME}/Desktop/config
        bootstrap: true
如果您使用引导标志,则 Config Server 需要在其 bootstrap.yml 中配置其名称和仓库 URI。

要更改服务器端点的位置,您可以(可选地)设置 spring.cloud.config.server.prefix(例如,/config),以在前缀下提供资源。前缀应以 / 开头但不以 / 结尾。它应用于 Config Server 中的 @RequestMappings(即,在 Spring Boot server.servletPathserver.contextPath 前缀之下)。

如果您想直接从后端仓库(而不是从配置服务器)读取应用程序的配置,您基本上需要一个没有端点的嵌入式配置服务器。您可以通过不使用 @EnableConfigServer 注解来完全关闭端点(设置 spring.cloud.config.server.bootstrap=true)。

推送通知和 Spring Cloud Bus

许多源代码仓库提供商(如 Github、Gitlab、Gitea、Gitee、Gogs 或 Bitbucket)通过 Webhook 通知您仓库中的更改。您可以通过提供商的用户界面将 Webhook 配置为 URL 和一组您感兴趣的事件。例如,Github 使用 POST 请求到 Webhook,其中包含一个包含提交列表的 JSON 主体和一个设置为 push 的标头(X-Github-Event)。如果您添加对 spring-cloud-config-monitor 库的依赖并在 Config Server 中激活 Spring Cloud Bus,则会启用 /monitor 端点。

当 Webhook 激活时,Config Server 会向其认为可能已更改的应用程序发送 RefreshRemoteApplicationEvent。更改检测可以策略化。但是,默认情况下,它会在与应用程序名称匹配的文件中查找更改(例如,foo.properties 针对 foo 应用程序,而 application.properties 针对所有应用程序)。当您想要覆盖此行为时使用的策略是 PropertyPathNotificationExtractor,它接受请求头和请求体作为参数,并返回已更改的文件路径列表。

默认配置与 Github、Gitlab、Gitea、Gitee、Gogs 或 Bitbucket 开箱即用。除了来自 Github、Gitlab、Gitee 或 Bitbucket 的 JSON 通知外,您还可以通过向 /monitor POST 请求并使用 path={application} 模式的表单编码主体参数来触发更改通知。这样做会向与 {application} 模式匹配的应用程序(可以包含通配符)广播。

RefreshRemoteApplicationEvent 仅当 spring-cloud-bus 在 Config Server 和客户端应用程序中都被激活时才传输。
默认配置还检测本地 git 仓库中的文件系统更改。在这种情况下,不使用 Webhook。但是,一旦您编辑配置文件,就会广播刷新。

AOT 和原生镜像支持

4.0.0 起,Spring Cloud Config Server 支持 Spring AOT 转换。然而,目前不支持 GraalVM 原生镜像。实现原生镜像支持受到 graal#5134 的阻碍,并且可能需要完成 https://github.com/graalvm/taming-build-time-initialization 上的工作才能修复。

Spring Cloud Config 客户端

Spring Boot 应用程序可以立即利用 Spring Config Server(或应用程序开发人员提供的其他外部属性源)。它还具有一些与 Environment 更改事件相关的额外有用功能。

Spring Boot 配置数据导入

Spring Boot 2.4 引入了一种通过 spring.config.import 属性导入配置数据的新方法。这现在是绑定到 Config Server 的默认方式。

要在 application.properties 中可选地连接到配置服务器,请进行以下设置:

application.properties
spring.config.import=optional:configserver:

这将连接到默认位置“https://:8888”的 Config Server。删除 optional: 前缀将导致 Config Client 在无法连接到 Config Server 时失败。要更改 Config Server 的位置,请设置 spring.cloud.config.uri 或将 URL 添加到 spring.config.import 语句,例如 spring.config.import=optional:configserver:http://myhost:8888。导入属性中的位置优先于 uri 属性。

Spring Boot 配置数据通过两步过程解析配置。首先,它使用 default 配置文件加载所有配置。这允许 Spring Boot 收集可能激活任何附加配置文件的所有配置。在收集所有已激活的配置文件后,它将加载活动配置文件的任何附加配置。因此,您可能会看到对 Spring Cloud Config Server 发出多个请求以获取配置。这是正常的,并且是 Spring Boot 在使用 spring.config.import 时加载配置的副作用。在 Spring Cloud Config 的早期版本中,只发出一个请求,但这意味​​着您无法从 Config Server 的配置中激活配置文件。现在,使用“default”配置文件发出的额外请求使这成为可能。

通过spring.config.import的Spring Boot配置数据导入方法不需要bootstrap文件(properties或yaml)。

配置优先引导

要使用旧版引导方式连接到 Config Server,必须通过属性或 spring-cloud-starter-bootstrap 启动器启用引导。该属性是 spring.cloud.bootstrap.enabled=true。它必须设置为系统属性或环境变量。一旦启用了引导,类路径中带有 Spring Cloud Config Client 的任何应用程序都将按如下方式连接到 Config Server:当配置客户端启动时,它会绑定到 Config Server(通过 spring.cloud.config.uri 引导配置属性),并使用远程属性源初始化 Spring Environment

这种行为的最终结果是,所有想要使用 Config Server 的客户端应用程序都需要一个 bootstrap.yml(或一个环境变量),其中在 spring.cloud.config.uri 中设置了服务器地址(默认为“https://:8888”)。

服务发现优先查找

除非您使用配置优先引导,否则您需要在配置属性中有一个带有 optional: 前缀的 spring.config.import 属性。例如,spring.config.import=optional:configserver:

如果您使用 DiscoveryClient 实现,例如 Spring Cloud Netflix 和 Eureka Service Discovery 或 Spring Cloud Consul,您可以让 Config Server 向 Discovery Service 注册。

如果您更喜欢使用 DiscoveryClient 来定位 Config Server,您可以通过设置 spring.cloud.config.discovery.enabled=true 来实现(默认为 false)。例如,使用 Spring Cloud Netflix,您需要定义 Eureka 服务器地址(例如,在 eureka.client.serviceUrl.defaultZone 中)。使用此选项的代价是在启动时进行额外的网络往返以定位服务注册。好处是,只要 Discovery Service 是固定点,Config Server 就可以更改其坐标。默认服务 ID 是 configserver,但您可以通过设置 spring.cloud.config.discovery.serviceId 在客户端上更改它(在服务器上,以服务通常的方式,例如通过设置 spring.application.name)。

服务发现客户端实现都支持某种元数据映射(例如,Eureka 有 eureka.instance.metadataMap)。Config Server 的一些附加属性可能需要在其服务注册元数据中进行配置,以便客户端能够正确连接。如果 Config Server 使用 HTTP Basic 进行保护,您可以将凭据配置为 userpassword。此外,如果 Config Server 具有上下文路径,您可以设置 configPath。例如,以下 YAML 文件适用于作为 Eureka 客户端的 Config Server:

eureka:
  instance:
    ...
    metadataMap:
      user: osufhalskjrtl
      password: lviuhlszvaorhvlo5847
      configPath: /config

使用 Eureka 和 WebClient 的服务发现优先引导

如果您使用 Spring Cloud Netflix 中的 Eureka DiscoveryClient,并且还想使用 WebClient 而不是 Jersey 或 RestTemplate,您需要在类路径中包含 WebClient 并设置 eureka.client.webclient.enabled=true

Config Client 快速失败

在某些情况下,如果服务无法连接到 Config Server,您可能希望服务启动失败。如果这是期望的行为,请将引导配置属性 spring.cloud.config.fail-fast=true 设置为使客户端因异常而停止。

要使用 spring.config.import 获得类似的功能,只需省略 optional: 前缀。

Config Client 重试

如果您预计应用程序启动时配置服务器可能偶尔不可用,您可以在失败后使其继续尝试。首先,您需要设置 spring.cloud.config.fail-fast=true。然后,您需要在类路径中添加 spring-retryspring-boot-starter-aop。默认行为是重试六次,初始回退间隔为 1000 毫秒,后续回退的指数乘数为 1.1。您可以通过设置 spring.cloud.config.retry.* 配置属性来配置这些属性(和其他属性)。要使用随机指数回退策略,请将 spring.cloud.config.retry.useRandomPolicy 设置为 true

要完全控制重试行为并使用旧版引导,请添加一个 ID 为 configServerRetryInterceptorRetryOperationsInterceptor 类型的 @Bean。Spring Retry 有一个 RetryInterceptorBuilder 支持创建这样的 Bean。

使用 spring.config.import 进行 Config Client 重试

重试适用于 Spring Boot spring.config.import 语句和正常属性。但是,如果导入语句位于配置文件中,例如 application-prod.properties,那么您需要不同的方式来配置重试。配置需要作为 URL 参数放置在导入语句上。

application-prod.properties
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.* 配置属性。

定位远程配置资源

Config Service 从 /{application}/{profile}/{label} 提供属性源,其中客户端应用程序中的默认绑定如下:

  • "application" = ${spring.application.name}

  • "profile" = ${spring.profiles.active} (实际上是 Environment.getActiveProfiles())

  • "label" = "master"

设置属性 ${spring.application.name} 时,请勿使用保留字 application- 作为应用程序名称的前缀,以防止解析正确的属性源时出现问题。

您可以通过设置 spring.cloud.config.*(其中 *nameprofilelabel)来覆盖它们。label 对于回滚到以前版本的配置很有用。使用默认的 Config Server 实现,它可以是 git 标签、分支名称或提交 ID。标签也可以作为逗号分隔的列表提供。在这种情况下,列表中的项将逐个尝试,直到一个成功。当在功能分支上工作时,这种行为可能很有用。例如,您可能希望将配置标签与您的分支对齐,但使其可选(在这种情况下,使用 spring.cloud.config.label=myfeature,develop)。

为配置服务器指定多个 URL

为了确保在部署了多个 Config Server 实例并且预计一个或多个实例有时不可用或无法处理请求(例如,如果 Git 服务器宕机)时实现高可用性,您可以指定多个 URL(作为 spring.cloud.config.uri 属性下的逗号分隔列表),或者让所有实例在服务注册中心(如 Eureka,如果使用 Discovery-First Bootstrap 模式)中注册。

spring.cloud.config.uri 下列出的 URL 将按列出的顺序尝试。默认情况下,Config Client 将尝试从每个 URL 获取属性,直到尝试成功,以确保高可用性。

但是,如果您只想在 Config Server 未运行时(即应用程序已退出)或发生连接超时时确保高可用性,请将 spring.cloud.config.multiple-uri-strategy 设置为 connection-timeout-only。(spring.cloud.config.multiple-uri-strategy 的默认值为 always。)例如,如果 Config Server 返回 500(Internal Server Error)响应或 Config Client 从 Config Server 收到 401(由于凭据错误或其他原因),则 Config Client 不会尝试从其他 URL 获取属性。400 错误(可能除了 404)表示用户问题而不是可用性问题。请注意,如果 Config Server 设置为使用 Git 服务器并且对 Git 服务器的调用失败,则可能会发生 404 错误。

可以在单个 spring.config.import 键下指定多个位置,而不是 spring.cloud.config.uri。位置将按照定义的顺序处理,后面的导入具有优先权。但是,如果 spring.cloud.config.fail-fasttrue,则如果第一次 Config Server 调用因任何原因失败,Config Client 将失败。如果 fail-fastfalse,它将尝试所有 URL,直到一个调用成功,无论失败的原因如何。(当在 spring.config.import 下指定 URL 时,spring.cloud.config.multiple-uri-strategy 不适用。)

如果您在 Config Server 上使用 HTTP 基本安全,目前仅当您将凭据嵌入到 spring.cloud.config.uri 属性下指定的每个 URL 中时,才可能支持每个 Config Server 的身份验证凭据。如果您使用任何其他类型的安全机制,您目前无法支持每个 Config Server 的身份验证和授权。

配置超时

如果您想配置超时阈值:

  • 读取超时可以通过使用属性 spring.cloud.config.request-read-timeout 进行配置。

  • 连接超时可以通过使用属性 spring.cloud.config.request-connect-timeout 进行配置。

安全

如果您在服务器上使用 HTTP Basic 安全,客户端需要知道密码(如果不是默认用户名,还需要知道用户名)。您可以通过配置服务器 URI 或通过单独的用户名和密码属性指定用户名和密码,如以下示例所示:

spring:
  cloud:
    config:
     uri: https://user:[email protected]

以下示例展示了传递相同信息的另一种方式:

spring:
  cloud:
    config:
     uri: https://myconfig.mycompany.com
     username: user
     password: secret

spring.cloud.config.passwordspring.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-typespring.cloud.config.tls.trust-store-type 的默认值为 PKCS12。省略密码属性时,假定为空密码。

如果您使用其他形式的安全性,您可能需要向 ConfigServicePropertySourceLocator 提供一个 RestTemplate(例如,通过在引导上下文中获取并注入它)。

健康指示器

Config Client 提供了一个 Spring Boot Health Indicator,它尝试从 Config Server 加载配置。可以通过设置 health.config.enabled=false 来禁用健康指示器。出于性能原因,响应也会被缓存。默认的缓存存活时间是 5 分钟。要更改该值,请设置 health.config.time-to-live 属性(以毫秒为单位)。

提供自定义 RestTemplate

在某些情况下,您可能需要自定义从客户端向配置服务器发出的请求。通常,这涉及传递特殊的 Authorization 标头以对服务器的请求进行身份验证。

使用配置数据提供自定义 RestTemplate

在使用配置数据时提供自定义 RestTemplate

  1. 创建实现 BootstrapRegistryInitializer 的类:

    CustomBootstrapRegistryInitializer.java
    public class CustomBootstrapRegistryInitializer implements BootstrapRegistryInitializer {
    
    	@Override
    	public void initialize(BootstrapRegistry registry) {
    		registry.register(RestTemplate.class, context -> {
    			RestTemplate restTemplate = new RestTemplate();
    			// Customize RestTemplate here
    			return restTemplate;
    		});
    	}
    
    }
    
  2. resources/META-INF 中,创建一个名为 spring.factories 的文件,并指定您的自定义配置,如以下示例所示:

    spring.factories
    org.springframework.boot.BootstrapRegistryInitializer=com.my.config.client.CustomBootstrapRegistryInitializer
使用引导提供自定义 RestTemplate

在使用 Bootstrap 时提供自定义 RestTemplate

  1. 创建一个新的配置 Bean,其中包含 PropertySourceLocator 的实现,如以下示例所示:

    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.* 属性。
  2. resources/META-INF 中,创建一个名为 spring.factories 的文件,并指定您的自定义配置,如以下示例所示:

    spring.factories
    org.springframework.cloud.bootstrap.BootstrapConfiguration = com.my.config.client.CustomConfigServiceBootstrapConfiguration

Vault

当使用 Vault 作为配置服务器的后端时,客户端需要提供一个令牌,供服务器从 Vault 中检索值。可以在客户端中通过在 bootstrap.yml 中设置 spring.cloud.config.token 来提供此令牌,如以下示例所示:

spring:
  cloud:
    config:
      token: YourVaultToken

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 原生镜像。

AOT 和原生镜像支持不适用于配置优先引导(使用 spring.config.use-legacy-processing=true)。
原生镜像不支持刷新范围。如果你将把你的配置客户端应用程序作为原生镜像运行,请确保将 spring.cloud.refresh.enabled 属性设置为 false
在构建包含 Spring Cloud Config Client 的项目时,您必须确保它连接到的配置数据源(例如,Spring Cloud Config Server、Consul、Zookeeper、Vault 等)可用。例如,如果您从 Spring Cloud Config Server 检索配置数据,请确保其实例正在运行并在 Config Client 设置中指示的端口可用。这是必要的,因为应用程序上下文是在构建时优化的,并且需要解析目标环境。
由于在 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 定义)。类型 long task timer

在启动观测后添加的键值可能会从 *.active 指标中缺失。
Micrometer 内部使用 纳秒 作为基本单位。但是,每个后端确定实际的基本单位。(即 Prometheus 使用秒)

封闭类的完全限定名 org.springframework.cloud.config.server.environment.DocumentedConfigObservation

所有标签都必须以 spring.cloud.config.environment 前缀开头!
表 4. 低基数键

名称

描述

spring.cloud.config.environment.application (必需)

正在查询属性的应用程序名称。

spring.cloud.config.environment.class (必需)

EnvironmentRepository 的实现。

spring.cloud.config.environment.label (必需)

正在查询属性的标签。

spring.cloud.config.environment.profile (必需)

正在查询属性的应用程序名称。

可观察性 - 跨度

以下是本项目声明的所有 Span 列表。

环境仓库跨度

围绕 EnvironmentRepository 创建的观察。

跨度名称 spring.cloud.config.environment.find (由约定类 org.springframework.cloud.config.server.environment.ObservationEnvironmentRepositoryObservationConvention 定义)。

封闭类的完全限定名 org.springframework.cloud.config.server.environment.DocumentedConfigObservation

所有标签都必须以 spring.cloud.config.environment 前缀开头!
表 5. 标签键

名称

描述

spring.cloud.config.environment.application (必需)

正在查询属性的应用程序名称。

spring.cloud.config.environment.class (必需)

EnvironmentRepository 的实现。

spring.cloud.config.environment.label (必需)

正在查询属性的标签。

spring.cloud.config.environment.profile (必需)

正在查询属性的应用程序名称。

© . This site is unofficial and not affiliated with VMware.