集中式配置

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

您将构建的内容

您将设置一个 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 分叉项目并在您的 IDE 或其他编辑器中打开它。

启动 Config Server

首先,您需要一个 Config Service 作为 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://www.apache.org/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);
  }
}

Config Server 需要知道要管理哪个存储库。这里有几种选择,但首先从基于 Git 的文件系统存储库开始。您可以轻松地将 Config Server 指向 Github 或 GitLab 存储库。在文件系统上,创建一个新目录并在其中运行 git init。然后将名为 a-bootiful-client.properties 的文件添加到 Git 存储库中。然后在其中运行 git commit。稍后,您将使用 Spring Boot 应用程序连接到 Config Server,该应用程序的 spring.application.name 属性将其标识为 a-bootiful-client 到 Config Server。这就是 Config Server 如何知道将哪组配置发送到特定客户端的方式。它发送 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

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

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

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

使用 Config Client 从 Config Server 读取配置

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

配置 Config Client 的属性可以通过 Spring Boot 应用程序的常用方式设置。在 configuration-client/src/main/resources/application.properties 中将客户端的 spring.application.name 指定为 a-bootiful-client 并指定 Config Server 的位置(spring.config.import)。以下清单显示了该文件

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

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

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

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

默认情况下,配置值在客户端启动时读取,之后不再读取。您可以通过使用 Spring Cloud Config 的 @RefreshScope 注解 MessageRestController 并随后触发刷新事件来强制 bean 刷新其配置(即,从 Config Server 获取更新的值)。以下清单(来自 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://www.apache.org/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;
  }
}

测试应用程序

您可以通过首先启动 Config Service,然后在它运行后启动客户端来测试端到端结果。在浏览器中访问客户端应用程序,网址为 https://127.0.0.1:8080/message。在那里,您应该在响应中看到 Hello world

将 Git 存储库中 a-bootiful-client.properties 文件中的 message 密钥更改为其他内容(例如 Hello Spring!)。您可以通过访问 https://127.0.0.1:8888/a-bootiful-client/default 来确认 Config Server 是否看到了更改。您需要调用 refresh Spring Boot Actuator 端点才能强制客户端刷新自身并引入新值。Spring Boot 的 Actuator 公开了有关应用程序的操作端点(例如健康检查和环境信息)。要使用它,您必须将 org.springframework.boot:spring-boot-starter-actuator 添加到客户端应用程序的类路径中。您可以通过向客户端的 refresh 端点发送空的 HTTP POST 请求来调用 refresh Actuator 端点:https://127.0.0.1:8080/actuator/refresh。然后,您可以通过访问 https://127.0.0.1:8080/message 端点来确认它是否有效。

以下命令调用 Actuator 的 refresh 命令

$ 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 许可证发布代码,并采用 署名-非衍生作品创作共用许可证 发布文本。

获取代码