/*
* 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);
}
}
集中式配置
本指南将引导您完成从 Spring Cloud Config Server 启动和使用配置的过程
您将构建的内容
您将设置一个 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
目录 -
跳至 启动 Config Server。
完成后,您可以将您的结果与 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 分叉项目并在您的 IDE 或其他编辑器中打开它。 |
启动 Config Server
首先,您需要一个 Config Service 作为 Spring 应用程序和(通常是)版本控制的配置文件存储库之间的中间体。您可以使用 Spring Cloud 的 @EnableConfigServer
来启动可以与其他应用程序通信的配置服务器。这是一个普通的 Spring Boot 应用程序,添加了一个注释来启用配置服务器。以下清单(来自 configuration-service/src/main/java/com/example/configurationservice/ConfigurationServiceApplication.java
)显示了这样一个应用程序
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.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
此示例使用基于文件的 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.properties
或 application.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 将所有服务的配置集中化,方法是首先启动一个服务,然后动态更新其配置。