集中式配置

本指南将引导您完成从 Spring Cloud Config Server 建立和使用配置的过程

您将构建什么

您将建立一个 配置服务器 并构建一个客户端,该客户端在启动时使用配置,然后在不重启客户端的情况下刷新配置。

您需要什么

如何完成本指南

与大多数 Spring 入门指南一样,您可以从头开始并完成每个步骤,也可以跳过您已熟悉的基本设置步骤。无论哪种方式,您最终都会得到可工作的代码。

从头开始,请转到从 Spring Initializr 开始

跳过基础知识,请执行以下操作

完成后,您可以对照 gs-centralized-configuration/complete 中的代码检查您的结果。

从 Spring Initializr 开始

您可以使用此 预初始化项目(用于服务应用程序)或此 预初始化项目(用于客户端应用程序),然后单击“生成”下载 ZIP 文件。此项目配置为符合本教程中的示例。

手动初始化项目

  1. 导航到 https://start.spring.io。此服务会为您拉取应用程序所需的所有依赖项,并为您完成大部分设置。

  2. 选择 Gradle 或 Maven 以及您想要使用的语言。本指南假设您选择了 Java。

  3. 单击依赖项并选择Config Server(用于服务应用程序)或Config ClientSpring Boot ActuatorSpring Web(用于客户端应用程序)。

  4. 单击生成

  5. 下载生成的 ZIP 文件,这是一个已根据您的选择配置好的 Web 应用程序存档。

如果您的 IDE 集成了 Spring Initializr,您可以从 IDE 中完成此过程。
您还可以从 Github fork 该项目并在您的 IDE 或其他编辑器中打开它。

建立配置服务器

您首先需要一个配置服务作为 Spring 应用程序与(通常)版本控制的配置文件存储库之间的中介。您可以使用 Spring Cloud 的 @EnableConfigServer 来建立一个可以与其他应用程序通信的配置服务器。这是一个普通的 Spring Boot 应用程序,只添加了一个注解来启用配置服务器。以下清单(来自 configuration-service/src/main/java/com/example/configurationservice/ConfigurationServiceApplication.java)展示了这样一个应用程序

/*
 * Copyright 2012-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://apache.ac.cn/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.configurationservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@EnableConfigServer
@SpringBootApplication
public class ConfigurationServiceApplication {

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

配置服务器需要知道要管理哪个存储库。这里有几种选择,但从基于 Git 文件系统的存储库开始。您可以同样轻松地将配置服务器指向 Github 或 GitLab 存储库。在文件系统上,创建一个新目录并在其中运行 git init。然后将一个名为 a-bootiful-client.properties 的文件添加到 Git 存储库。然后运行 git commit。稍后,您将使用一个 Spring Boot 应用程序连接到配置服务器,该应用程序的 spring.application.name 属性将其标识为配置服务器的 a-bootiful-client。这就是配置服务器如何知道要向特定客户端发送哪组配置。它发送 Git 存储库中任何名为 application.propertiesapplication.yml 的文件中的所有值。更具体命名的文件(如 a-bootiful-client.properties)中的属性键会覆盖 application.propertiesapplication.yml 中的属性键。

向新创建的 a-bootiful-client.properties 文件添加一个简单的属性和值 (message = Hello world),然后 git commit 更改。

通过在 configuration-service/src/main/resources/application.properties 中指定 spring.cloud.config.server.git.uri 属性来指定 Git 存储库的路径。您还必须指定不同的 server.port 值,以避免在同一台机器上运行此服务器和另一个 Spring Boot 应用程序时发生端口冲突。以下清单(来自 configuration-service/src/main/resources/application.properties)显示了这样一个 application.properties 文件

server.port=8888

spring.cloud.config.server.git.uri=${HOME}/Desktop/config

此示例使用位于 ${HOME}/Desktop/config 的基于文件的 git 存储库。您可以轻松地通过创建一个新目录并在其中对属性和 YAML 文件运行 git commit 来创建一个。以下命令集完成了这项工作

$ cd ~/Desktop/config
$ find .
./.git
...
./application.yml

或者,如果您更改应用程序中的配置文件以指向远程 git 存储库(如 Github),您也可以使用远程 git 存储库。

使用配置客户端从配置服务器读取配置

现在您已经建立了一个配置服务器,您需要建立一个新的 Spring Boot 应用程序,该应用程序使用配置服务器加载其自己的配置,并且按需刷新其配置以反映配置服务器的更改,而无需重新启动 JVM。为此,添加 org.springframework.cloud:spring-cloud-starter-config 依赖项,以连接到配置服务器。Spring 会将配置文件视为从 application.propertiesapplication.yml 或任何其他 PropertySource 加载的任何属性文件。

配置配置客户端的属性可以像 Spring Boot 应用程序通常那样设置。在 configuration-client/src/main/resources/application.properties 中将客户端的 spring.application.name 指定为 a-bootiful-client,并将配置服务器的位置 (spring.config.import) 指定出来。以下清单显示了该文件

configuration-client/src/main/resources/application.properties

spring.application.name=a-bootiful-client
spring.config.import=optional:configserver:https://:8888/
management.endpoints.web.exposure.include=*

您还希望启用 /refresh 端点,以演示动态配置更改。上面的清单显示了如何通过 management.endpoints.web.exposure.include 属性来实现这一点。

客户端可以通过传统机制(例如 @ConfigurationProperties@Value("${...​}") 或通过 Environment 抽象)访问配置服务器中的任何值。现在您需要创建一个 Spring MVC REST 控制器,该控制器返回已解析的 message 属性的值。请参阅 构建 RESTful Web 服务 指南,了解有关使用 Spring MVC 和 Spring Boot 构建 REST 服务的更多信息。

默认情况下,配置值在客户端启动时读取,之后不再读取。您可以通过使用 Spring Cloud Config 的 @RefreshScope 注解 MessageRestController,然后触发一个刷新事件来强制 bean 刷新其配置(即从配置服务器拉取更新的值)。以下清单(来自 configuration-client/src/main/java/com/example/configurationclient/ConfigurationClientApplication.java)显示了如何实现这一点

/*
 * Copyright 2012-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://apache.ac.cn/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.configurationclient;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class ConfigurationClientApplication {

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

@RefreshScope
@RestController
class MessageRestController {

  @Value("${message:Hello default}")
  private String message;

  @RequestMapping("/message")
  String getMessage() {
    return this.message;
  }
}

测试应用程序

您可以通过先启动配置服务,然后一旦它运行起来,再启动客户端来测试端到端的结果。在浏览器中访问客户端应用程序:https://:8080/message。在那里,您应该在响应中看到 Hello world

将 Git 存储库中 a-bootiful-client.properties 文件中的 message 键更改为不同的内容(也许是 Hello Spring!?)。您可以通过访问 https://:8888/a-bootiful-client/default 来确认配置服务器看到了更改。您需要调用 refresh Spring Boot Actuator 端点,以强制客户端刷新自身并获取新值。Spring Boot 的 Actuator 暴露了有关应用程序的操作端点(例如健康检查和环境信息)。要使用它,您必须将 org.springframework.boot:spring-boot-starter-actuator 添加到客户端应用程序的类路径中。您可以通过向客户端的 refresh 端点发送一个空的 HTTP POST 来调用 refresh Actuator 端点:https://:8080/actuator/refresh。然后,您可以通过访问 https://:8080/message 端点来确认它是否起作用。

以下命令调用 Actuator 的刷新命令

$ curl -X POST localhost:8080/actuator/refresh -d {} -H "Content-Type: application/json"
我们在客户端应用程序中设置了 management.endpoints.web.exposure.include=* 以便轻松测试(因为从 Spring Boot 2.0 开始,Actuator 端点默认不暴露)。默认情况下,如果您不设置该标志,您仍然可以通过 JMX 访问它们。

总结

恭喜!您刚刚通过首先建立服务,然后动态更新其配置,使用 Spring 集中管理了所有服务的配置。

另请参阅

以下指南也可能有所帮助

想写新指南或为现有指南做贡献吗?请查看我们的贡献指南

所有指南的代码均采用 ASLv2 许可,文字内容采用署名-禁止演绎知识共享许可

获取代码