4.0.4

Spring Cloud Config 为分布式系统中的外部化配置提供服务器端和客户端支持。借助配置服务器,您可以在一个中心位置来管理所有环境中应用程序的外部属性。客户端和服务器上的概念与 SpringEnvironmentPropertySource抽象完全相同,因此它们非常适合 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)并使用它来初始化 mini 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.namein SpringApplication(通常application在常规 Spring Boot 应用程序中),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。还有一个spring-cloud-starter-parent针对 Maven 用户的父 pom 和 BOM ( ) 以及针对 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);
    }

}

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

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 of remote repository>/<file name>包含foo值为 的属性bar

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

Spring Cloud 配置服务器

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

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

与所有 Spring Boot 应用程序一样,它默认在端口 8080 上运行,但您可以通过各种方式将其切换到更常规的端口 8888。最简单的方法是使用(配置服务器 jar 中spring.config.name=configserver有一个)启动它,它还设置默认配置存储库。configserver.yml另一种方法是使用您自己的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 存储库仅用于测试。您应该使用服务器来托管生产中的配置存储库。
如果您仅在其中保留文本文件,则配置存储库的初始克隆可以快速高效。如果您存储二进制文件,尤其是大文件,则首次配置请求时可能会遇到延迟,或者在服务器中遇到内存不足错误。

环境存储库

您应该在哪里存储配置服务器的配置数据?控制这种行为的策略是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 应用程序一样,这些属性也可以通过环境变量或命令行参数设置)。

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

您可以设置spring.cloud.config.server.accept-emptyfalse,以便服务器在未找到应用程序时返回 HTTP 404 状态。默认情况下,该标志设置为true

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

Git 后端

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

此存储库实现将{label}HTTP 资源的参数映射到 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 中的占位符

{application}Spring Cloud Config Server 支持带有和占位符的 git 存储库 URL {profile}{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}不匹配任何模式,它将使用 下定义的默认 URI spring.cloud.config.server.git.uri。在上面的示例中,对于“简单”存储库,模式为simple/*(它仅匹配simple所有配置文件中指定的一个应用程序)。“本地”存储库匹配所有配置文件中以 开头的所有应用程序名称local/*后缀会自动添加到任何没有配置文件匹配器的模式)。

仅当要设置的唯一属性是 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,*"],依此类推)。这很常见,例如,您需要在本地“开发”配置文件中运行应用程序,但也需要远程运行“云”配置文件中的应用程序。

每个存储库还可以选择将配置文件存储在子目录中,并且可以将搜索这些目录的模式指定为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-repo,然后再接受任何请求。在请求存储库的配置之前,不会克隆所有其他存储库。

设置在 Config Server 启动时克隆存储库有助于在 Config Server 启动时快速识别配置错误的配置源(例如无效的存储库 URI)。如果cloneOnStart未启用配置源,配置服务器可能会使用错误配置或无效的配置源成功启动,并且在应用程序从该配置源请求配置之前不会检测到错误。
验证

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

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

~/.ssh如果您不使用 HTTPS 和用户凭据,当您将密钥存储在默认目录 ( ) 中并且 URI 指向 SSH 位置(例如 )时,SSH 也应该可以开箱即用git@github.com:configuration/cloud-configuration。文件中存在 Git 服务器条目~/.ssh/known_hosts并且格式正确非常重要ssh-rsaecdsa-sha2-nistp256不支持其他格式(例如)。为了避免意外,您应该确保 Git 服务器的文件中只存在一项known_hosts,并且它与您提供给配置服务器的 URL 相匹配。如果您在 URL 中使用主机名,则您希望文件中包含该主机名(而不是 IP)known_hosts。该存储库是通过使用 JGit 访问的,因此您找到的任何文档都应该适用。HTTPS 代理设置可以使用系统属性 (和)在 或 中设置~/.git/config(与任何其他 JVM 进程的方式相同)。-Dhttps.proxyHost-Dhttps.proxyPort

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

JGit 需要 PEM 格式的 RSA 密钥。下面是一个示例 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 服务器启动时,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身份验证。从命令行使用 Git 时,AWS CodeCommit 使用身份验证帮助程序。此帮助程序不与 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 角色

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

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-httpjar 不在您的类路径中,则无论 git 服务器 URI 为何,都不会创建 Google Cloud Source 凭据提供程序。
使用属性进行 Git SSH 配置

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

  spring:
    cloud:
      config:
        server:
          git:
            uri: git@gitserver.com: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 配置属性
物业名称 评论

忽略LocalSsh设置

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

私钥

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

主机密钥

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

主机密钥算法

其中之一ssh-dss, ssh-rsa, ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, or ecdsa-sha2-nistp521hostKey如果也设置了则必须设置。

严格的主机密钥检查

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

已知主机文件

自定义文件的位置.known_hosts

首选身份验证

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

Git 搜索路径中的占位符

{application}Spring Cloud Config Server 还支持带有and占位符的搜索路径{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 刷新率

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

默认标签

Git 使用的默认标签是main. 如果您不设置spring.cloud.config.server.git.defaultLabel并且名为 的分支main 不存在,则配置服务器默认情况下也会尝试签出名为 的分支master。如果您想禁用后备分支行为,您可以设置 spring.cloud.config.server.git.tryMasterBranchfalse

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

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

文件系统后端

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

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

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

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

保险库后端

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 可以将身份验证委托给该库。请将以下依赖项添加到您的配置服务器应用程序中。

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 属性:

姓名 默认值

主持人

127.0.0.1

港口

8200

方案

http

后端

秘密

默认密钥

应用

轮廓分隔符

,

kv版本

1

跳过SSL验证

错误的

暂停

5

名称空间

无效的

上表中的所有属性都必须带有前缀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 EnterpriseX-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" "http://localhost: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.http对于 Git 或 Vault,此行为由和下的设置控制proxy.https。这些设置针对每个存储库,因此如果您使用复合环境存储库,则必须为复合环境中的每个后端单独配置代理设置。如果使用的网络需要单独的 HTTP 和 HTTPS URL 代理服务器,您可以为单个后端配置 HTTP 和 HTTPS 代理设置:在这种情况下,访问将使用http代理httphttps访问该https后端。此外,您还可以使用应用程序和代理之间的代理定义协议指定一个单独的代理,该代理将用于这两种协议。

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

表 2. 代理配置属性
物业名称 评论

主持人

代理的主机。

港口

用于访问代理的端口。

非代理主机

配置服务器应在代理外部访问的任何主机。proxy.http.nonProxyHosts如果为 和都提供了值proxy.https.nonProxyHostsproxy.http则将使用该值。

用户名

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

密码

用于向代理进行身份验证的密码。proxy.http.password如果为 和都提供了值proxy.https.passwordproxy.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 和本机)的存储库,文件名为application*( application.propertiesapplication.ymlapplication-*.properties等) 的资源在所有客户端应用程序之间共享。您可以使用具有这些文件名的资源来配置全局默认值,并根据需要让它们被特定于应用程序的文件覆盖。

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

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

使用 Vault 作为后端时,您可以通过将配置放在secret/application. 例如,如果您运行以下 Vault 命令,则使用配置服务器的所有应用程序都将具有foo可用的属性baz

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

使用 CredHub 作为后端时,您可以通过将配置放入应用程序的配置文件中/application/或将其放入default应用程序的配置文件中来与所有应用程序共享配置。例如,如果您运行以下 CredHub 命令,则所有使用配置服务器的应用程序都将具有shared.color1可用的属性shared.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 秘密管理器

/application/使用 AWS Secrets Manager 作为后端时,您可以通过将配置放入应用程序的配置文件中或将其放入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 后端一样保留配置环境的标记版本。

存储库实现将{label}HTTP 资源的参数映射到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 后端部分描述的(_)方式相同。

AWS 参数存储

使用 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配置文件或添加类型为 的 bean 来启用此功能JdbcEnvironmentRepository。如果您在类路径中包含正确的依赖项(有关更多详细信息,请参阅用户指南),Spring Boot 会配置数据源。

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

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

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 DataRedisTemplate访问 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 作为配置属性的后端。您可以通过添加对适用于 Amazon S3 的 AWS Java SDK 的依赖项来启用此功能。

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 来覆盖S3 服务的标准终端节点spring.cloud.config.server.awss3.endpoint。这允许支持 S3 的 beta 区域以及其他 S3 兼容的存储 API。

使用Default Credential Provider Chain查找凭证。支持版本化和加密的存储桶,无需进一步配置。

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

当没有指定配置文件时,default将使用。

AWS 参数存储后端

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 配置属性
物业名称 必需的 默认值 评论

地区

AWS Parameter Store 客户端要使用的区域。如果未明确设置,SDK 会尝试使用Default Region Provider Chain来确定要使用的区域。

终点

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

起源

aws:ssm:parameter:

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

字首

/config

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

轮廓分隔符

-

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

递归的

true

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

解密值

true

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

最大结果

10

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

AWS Parameter Store API 凭证是使用Default Credential Provider Chain确定的。返回最新版本的默认行为已支持版本化参数。

  • 未指定应用程序时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 凭证是使用Default Credential Provider Chain确定的。

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

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
}
当未指定配置文件时,default将使用该配置文件;当未指定标签时,master将使用默认值。注意:添加的值application将由所有应用程序共享。
OAuth 2.0

您可以使用UAA作为提供者通过OAuth 2.0进行身份验证。

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范围。

复合环境存储库

在某些情况下,您可能希望从多个环境存储库中提取配置数据。为此,您可以composite在配置服务器的应用程序属性或 YAML 文件中启用配置文件。例如,如果您想要从 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 存储库之一中找到的相同属性的值。在 Git 存储库中找到的值rex将先于在 Git 存储库中找到的相同属性的值使用walter

如果您只想从不同类型的存储库中提取配置数据,则可以composite在配置服务器的应用程序属性或 YAML 文件中启用相应的配置文件,而不是配置文件。例如,如果您想要从单个 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 令牌。请参阅保管库后端
从环境存储库检索值时的任何类型的失败都会导致整个复合环境失败。如果您希望复合即使在存储库失败时也能继续,您可以设置spring.cloud.config.server.failOnCompositeErrorfalse
使用复合环境时,所有存储库都包含相同的标签非常重要。如果您的环境与前面的示例类似,并且您请求带有 标签的配置数据,master但 Subversion 存储库不包含名为 的分支master,则整个请求将失败。
自定义复合环境存储库

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

属性覆盖

配置服务器具有“覆盖”功能,允许操作员向所有应用程序提供配置属性。使用普通 Spring Boot 挂钩的应用程序不会意外更改覆盖的属性。要声明覆盖,请将名称-值对的映射添加到spring.cloud.config.server.overrides,如以下示例所示:

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

前面的示例导致作为配置客户端的所有应用程序读取foo=bar,而与它们自己的配置无关。

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

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

使用 Bootstrap 覆盖属性

如果启用config first bootstrap,则可以通过在来自配置服务器的应用程序配置中放置两个属性来允许客户端应用程序覆盖来自配置服务器的配置。

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

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

使用占位符覆盖属性

在不启用配置优先引导的情况下覆盖属性的一种更简洁的方法是在来自配置服务器的配置中使用属性占位符。

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

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

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

app.hello=Hello From Application!

使用配置文件覆盖属性

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

例如,如果您从配置服务器具有以下配置

hello="Hello From Config Server!"

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

应用程序覆盖.properties
hello="Hello From Application!"

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

健康指标

配置服务器附带一个健康指示器,用于检查配置是否EnvironmentRepository正常工作。默认情况下,它会要求EnvironmentRepository名为 的应用程序appdefault配置文件以及实现提供的默认标签EnvironmentRepository

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

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

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

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

安全

您可以通过任何对您有意义的方式来保护您的配置服务器(从物理网络安全到 OAuth2 不记名令牌),因为 Spring Security 和 Spring Boot 为许多安全安排提供支持。

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

执行器和安全

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

加密与解密

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

如果远程属性源包含加密内容(以 开头的值{cipher}),则它们会在通过 HTTP 发送到客户端之前被解密。此设置的主要优点是属性值在“静止”时(例如,在 git 存储库中)不需要采用纯文本形式。如果某个值无法解密,则会将其从属性源中删除,并使用相同的密钥添加一个附加属性,但前缀为invalid和 ,表示“不适用”(通常为<n/a>)。这主要是为了防止密文被用作密码而意外泄露。

如果您为配置客户端应用程序设置远程配置存储库,它可能包含application.yml类似于以下内容的内容:

应用程序.yml
spring:
  datasource:
    username: dbuser
    password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ'

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

应用程序属性
spring.datasource.username: dbuser
spring.datasource.password: {cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ

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

服务器还公开/encrypt端点/decrypt(假设这些端点是安全的并且仅由授权代理访问)。如果编辑远程配置文件,则可以使用配置服务器通过 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

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

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

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

命令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参数是强制性的(尽管有--前缀)。

密钥管理

配置服务器可以使用对称(共享)密钥或非对称密钥(RSA 密钥对)。非对称选择在安全性方面更优越,但使用对称密钥通常更方便,因为它是在application.properties.

要配置对称密钥,您需要设置encrypt.key为秘密字符串(或使用ENCRYPT_KEY环境变量以使其远离纯文本配置文件)。

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

要配置非对称密钥,请使用密钥库(例如,由keytoolJDK 附带的实用程序创建的密钥库)。密钥库属性encrypt.keyStore.*等于*

财产 描述

encrypt.keyStore.location

包含一个Resource位置

encrypt.keyStore.password

保存解锁密钥库的密码

encrypt.keyStore.alias

标识要使用商店中的哪个密钥

encrypt.keyStore.type

要创建的密钥库的类型。默认为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文件放入类路径中(例如),然后在您的bootstrap.ymlConfig Server 中创建以下设置:

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

使用多个密钥和密钥轮换

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

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

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

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

如果您想让配置服务器处理所有加密和解密,{name:value}也可以将前缀添加为发布到/encrypt端点的纯文本。

提供加密属性

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

提供替代格式

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

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

使用 YAML 或属性格式存在限制,主要与元数据的丢失有关。例如,JSON 的结构为属性源的有序列表,其名称与源相关。即使值的来源有多个源,YAML 和属性表单也会合并到单个映射中,并且原始源文件的名称会丢失。此外,YAML 表示也不一定是后备存储库中 YAML 源的忠实表示。它是根据扁平属性源列表构建的,并且必须对密钥的形式做出假设。

提供纯文本服务

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

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

与环境配置的源文件一样,profile用于解析文件名。因此,如果您想要一个特定于配置文件的文件,可以通过名为(优先于)/*/development/*/logback.xml的文件来解决。 logback-development.xmllogback.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 参考指南中所述。

解密纯文本

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

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

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

嵌入配置服务器

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

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

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

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

推送通知和 Spring Cloud Bus

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

当 webhook 被激活时,配置服务器会RefreshRemoteApplicationEvent向它认为可能已更改的应用程序发送一个目标。变化检测可以制定策略。但是,默认情况下,它会查找与应用程序名称匹配的文件中的更改(例如,foo.properties针对该foo应用程序,而application.properties针对所有应用程序)。当您想要覆盖行为时使用的策略是PropertyPathNotificationExtractor,它接受请求标头和正文作为参数并返回已更改的文件路径列表。

默认配置可直接用于 Github、Gitlab、Gitea、Gitee、Gogs 或 Bitbucket。除了来自 Github、Gitlab、Gitee 或 Bitbucket 的 JSON 通知之外,您还可以通过 POST 到/monitor格式编码的正文参数来触发更改通知path={application}。这样做会广播到与{application}模式(可以包含通配符)匹配的应用程序。

RefreshRemoteApplicationEvent仅当spring-cloud-bus在配置服务器和客户端应用程序中都激活 时 才会传输。
默认配置还检测本地 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 配置客户端

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

Spring Boot 配置数据导入

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

要选择连接到配置服务器,请在 application.properties 中设置以下内容:

应用程序属性
spring.config.import=optional:configserver:

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

Spring Boot Config Data 通过两步过程解析配置。首先,它使用配置文件加载所有配置default 。这允许 Spring Boot 收集可能激活任何其他配置文件的所有配置。收集所有激活的配置文件后,它将加载活动配置文件的任何附加配置。因此,您可能会看到向 Spring Cloud Config Server 发出多个请求来获取配置。这是正常现象,是 Spring Boot 在使用spring.config.import. 在以前版本的 Spring Cloud Config 中,仅发出一个请求,但这意味着您无法从来自配置服务器的配置激活配置文件。现在,仅使用“默认”配置文件的附加请求使这成为可能。

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

配置第一个引导程序

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

此行为的最终结果是,所有想要使用配置服务器的客户端应用程序都需要一个bootstrap.yml(或环境变量)并设置服务器地址spring.cloud.config.uri(默认为“http://localhost:8888”)。

发现首次查找

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

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

如果您更喜欢使用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.instance.metadataMapEureka)。可能需要在其服务注册元数据中配置配置服务器的一些附加属性,以便客户端可以正确连接。如果配置服务器使用 HTTP Basic 进行保护,您可以将凭据配置为userpassword。另外,如果配置服务器有上下文路径,您可以设置configPath. 例如,以下 YAML 文件适用于作为 Eureka 客户端的配置服务器:

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

使用 Eureka 和 WebClient 发现第一个 Bootstrap

如果您使用 Spring Cloud Netflix 中的 EurekaDiscoveryClient并且还想使用WebClientJersey 或RestTemplate,则需要WebClient在类路径中包含 set eureka.client.webclient.enabled=true

配置客户端快速失败

在某些情况下,如果某个服务无法连接到配置服务器,您可能希望该服务启动失败。如果这是所需的行为,请设置引导配置属性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.*

要完全控制重试行为并使用旧版引导程序,请添加ID 为 的@Beanof 类型。Spring Retry 有一个支持创建一个。 RetryOperationsInterceptorconfigServerRetryInterceptorRetryInterceptorBuilder

使用 spring.config.import 配置客户端重试

Retry 适用于 Spring Bootspring.config.import语句,并且正常属性适用。但是,如果导入语句位于配置文件中,例如application-prod.properties,则您需要采用不同的方式来配置重试。配置需要作为 url 参数放置在 import 语句中。

应用程序产品属性
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},其中客户端应用程序中的默认绑定如下:

  • “应用”=${spring.application.name}

  • “个人资料”= ${spring.profiles.active}(实际上Environment.getActiveProfiles()

  • “标签”=“主控”

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

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

为配置服务器指定多个 URL

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

下面列出的 URLspring.cloud.config.uri将按列出的顺序进行尝试。默认情况下,配置客户端将尝试从每个 URL 获取属性,直到尝试成功以确保高可用性。

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

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

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

配置超时

如果要配置超时阈值:

  • 可以使用 属性来配置读取超时spring.cloud.config.request-read-timeout

  • 可以使用 属性来配置连接超时spring.cloud.config.request-connect-timeout

安全

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

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

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

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

如果您使用另一种形式的安全性,则可能需要提供 aRestTemplateConfigServicePropertySourceLocator例如,通过在引导上下文中获取它并注入它)。

健康指标

配置客户端提供了一个 Spring Boot 运行状况指示器,尝试从配置服务器加载配置。可以通过设置禁用健康指示器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并指定您的自定义配置,如以下示例所示:

    弹簧工厂
    org.springframework.boot.BootstrapRegistryInitializer=com.my.config.client.CustomBootstrapRegistryInitializer
使用 Bootstrap 提供自定义 RestTemplate

RestTemplate使用 Bootstrap 时提供自定义:

  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;
        }
    }
    
    对于添加标头的简化方法Authorizationspring.cloud.config.headers.*可以使用该属性。
  2. 在 中resources/META-INF,创建一个名为的文件 spring.factories并指定您的自定义配置,如以下示例所示:

    弹簧工厂
    org.springframework.cloud.bootstrap.BootstrapConfiguration = com.my.config.client.CustomConfigServiceBootstrapConfiguration

避难所

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

spring:
  cloud:
    config:
      token: YourVaultToken

Vault 中的嵌套键

Vault 支持在 Vault 中存储的值中嵌套键的功能,如以下示例所示:

echo -n '{"appA": {"secret": "appAsecret"}, "bar": "baz"}' | vault write secret/myapp -

此命令将 JSON 对象写入您的 Vault。要在 Spring 中访问这些值,您可以使用传统的 dot( .) 注释,如以下示例所示

@Value("${appA.secret}")
String name = "World";

前面的代码会将变量的值设置nameappAsecret

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),因此快速启动时间将因网络通信所需的时间而变慢。

附录

可观测性元数据

可观察性 - 指标

您可以在下面找到该项目声明的所有指标的列表。

环境存储库

围绕环境存储库创建的观察。

指标名称 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 指标中可能会缺少启动观察后添加的键值。
千分尺内部用作nanoseconds基本单元。然而,每个后端决定实际的基本单元。(即普罗米修斯使用秒)

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

所有标签必须加前缀spring.cloud.config.environmentprefix!
表 4. 低基数键

姓名

描述

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

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

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

环境存储库的实施。

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

正在查询属性的标签。

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

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

可观察性 - 跨度

您可以在下面找到该项目声明的所有跨度的列表。

环境存储库跨度

围绕环境存储库创建的观察。

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

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

所有标签必须加前缀spring.cloud.config.environmentprefix!
表 5. 标签键

姓名

描述

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

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

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

环境存储库的实施。

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

正在查询属性的标签。

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

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