/*
* 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 搭建和消费配置的过程。
您将构建什么
您将搭建一个 Config Server,并构建一个客户端,该客户端在启动时消费配置,然后在不重启客户端的情况下刷新配置。
您需要准备什么
-
约 15 分钟
-
喜欢的文本编辑器或 IDE
-
Java 17 或更高版本
-
您也可以直接将代码导入 IDE
如何完成本指南
与大多数 Spring 入门指南一样,您可以从头开始并完成每个步骤,或者跳过您已熟悉的基本设置步骤。无论哪种方式,您最终都会得到可工作的代码。
要从头开始,请继续阅读 从 Spring Initializr 开始。
要跳过基础步骤,请执行以下操作
-
下载并解压本指南的源代码仓库,或者使用 Git 克隆:
git clone https://github.com/spring-guides/gs-centralized-configuration.git
-
cd 进入
gs-centralized-configuration/initial
-
跳至 搭建 Config Server。
完成时,您可以对照 gs-centralized-configuration/complete
中的代码检查您的结果。
从 Spring Initializr 开始
手动初始化项目
-
导航至 https://start.spring.io。该服务会引入应用程序所需的所有依赖项,并为您完成大部分设置。
-
选择 Gradle 或 Maven,以及您想要使用的语言。本指南假设您选择 Java。
-
点击 Dependencies 并选择 Config Server(用于服务应用)或 Config Client、Spring Boot Actuator 和 Spring Web(用于客户端应用)。
-
点击 Generate。
-
下载生成的 ZIP 文件,这是一个根据您的选择配置的 Web 应用程序存档。
如果您的 IDE 集成了 Spring Initializr,您可以在 IDE 中完成此过程。 |
您也可以从 Github 分叉项目并在 IDE 或其他编辑器中打开。 |
搭建 Config Server
首先,您需要一个 Config Service 作为 Spring 应用程序和配置文件的(通常是)版本控制仓库之间的中间层。您可以使用 Spring Cloud 的 @EnableConfigServer
搭建一个可以与其他应用程序通信的 Config Server。这是一个普通的 Spring Boot 应用程序,添加了一个注解来启用 Config Server。以下清单(来自 configuration-service/src/main/java/com/example/configurationservice/ConfigurationServiceApplication.java
)展示了这样的应用程序
Config Server 需要知道管理哪个仓库。这里有几种选择,但我们从基于 Git 的文件系统仓库开始。您可以同样轻松地将 Config Server 指向 Github 或 GitLab 仓库。在文件系统上,创建一个新目录并在其中运行 git init
。然后向 Git 仓库添加一个名为 a-bootiful-client.properties
的文件。接着在其中运行 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
此示例使用位于 ${HOME}/Desktop/config
的基于文件的 Git 仓库。您只需创建一个新目录并在其中对属性和 YAML 文件运行 git commit
即可轻松创建一个。以下命令集完成了这项工作
$ cd ~/Desktop/config
$ find .
./.git
...
./application.yml
或者,如果您更改应用程序中的配置文件以指向远程 Git 仓库(例如 Github),您也可以使用远程 Git 仓库。
使用 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:http://localhost: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://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;
}
}
测试应用程序
您可以通过先启动 Config Service,然后在它运行后启动客户端来测试端到端结果。在浏览器中访问客户端应用程序 http://localhost:8080/message
。在那里,您应该在响应中看到 Hello world
。
将 Git 仓库中 a-bootiful-client.properties
文件中的 message
键更改为不同的值(也许是 Hello Spring!
?)。您可以通过访问 http://localhost:8888/a-bootiful-client/default
来确认 Config Server 是否看到了更改。您需要调用 refresh
Spring Boot Actuator 端点来强制客户端刷新自身并拉取新值。Spring Boot 的 Actuator 暴露了有关应用程序的操作端点(例如健康检查和环境信息)。要使用它,您必须将 org.springframework.boot:spring-boot-starter-actuator
添加到客户端应用程序的 classpath 中。您可以通过向客户端的 refresh
端点发送一个空的 HTTP POST
请求来调用 refresh
Actuator 端点:http://localhost:8080/actuator/refresh
。然后通过访问 http://localhost: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 许可证发布,文字内容采用署名-禁止演绎 (Attribution, NoDerivatives) 知识共享许可协议发布。 |