/*
* 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);
}
}
集中式配置
本指南将引导您完成从 Spring Cloud Config Server 建立和使用配置的过程
您将构建什么
您将建立一个 配置服务器 并构建一个客户端,该客户端在启动时使用配置,然后在不重启客户端的情况下刷新配置。
您需要什么
-
大约 15 分钟
-
一个喜欢的文本编辑器或 IDE
-
Java 17 或更高版本
-
您还可以将代码直接导入到您的 IDE 中
如何完成本指南
与大多数 Spring 入门指南一样,您可以从头开始并完成每个步骤,也可以跳过您已熟悉的基本设置步骤。无论哪种方式,您最终都会得到可工作的代码。
要从头开始,请转到从 Spring Initializr 开始。
要跳过基础知识,请执行以下操作
-
下载并解压本指南的源存储库,或使用 Git 克隆它:
git clone https://github.com/spring-guides/gs-centralized-configuration.git -
进入
gs-centralized-configuration/initial -
跳到 建立配置服务器。
完成后,您可以对照 gs-centralized-configuration/complete 中的代码检查您的结果。
从 Spring Initializr 开始
手动初始化项目
-
导航到 https://start.spring.io。此服务会为您拉取应用程序所需的所有依赖项,并为您完成大部分设置。
-
选择 Gradle 或 Maven 以及您想要使用的语言。本指南假设您选择了 Java。
-
单击依赖项并选择Config Server(用于服务应用程序)或Config Client、Spring Boot Actuator和Spring Web(用于客户端应用程序)。
-
单击生成。
-
下载生成的 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)展示了这样一个应用程序
配置服务器需要知道要管理哪个存储库。这里有几种选择,但从基于 Git 文件系统的存储库开始。您可以同样轻松地将配置服务器指向 Github 或 GitLab 存储库。在文件系统上,创建一个新目录并在其中运行 git init。然后将一个名为 a-bootiful-client.properties 的文件添加到 Git 存储库。然后运行 git commit。稍后,您将使用一个 Spring Boot 应用程序连接到配置服务器,该应用程序的 spring.application.name 属性将其标识为配置服务器的 a-bootiful-client。这就是配置服务器如何知道要向特定客户端发送哪组配置。它也发送 Git 存储库中任何名为 application.properties 或 application.yml 的文件中的所有值。更具体命名的文件(如 a-bootiful-client.properties)中的属性键会覆盖 application.properties 或 application.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.properties 或 application.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 集中管理了所有服务的配置。