1. 概述
在《Consul 极简入门》文章中,我们一起完成了 Consul 的学习,并完成了 Consul 服务器的搭建。
本文我们来学习 Spring Cloud Consul 提供的 spring-cloud-consul-config 组件,接入 Consul 作为配置中心,实现服务的统一配置管理。
2. 快速入门
示例代码对应仓库:labx-28-sc-consul-config-demo。
本小节,我们会在 Consul 服务中定义配置,并使用 @ConfigurationProperties 和 @Value 注解,读取该配置。
友情提示:如果胖友看过《Spring Boot 配置文件入门》的「2. 自定义配置」小节,就会发现本小节是对标这块的内容。
下面,我们来创建一个 labx-28-sc-consul-config-demo 示例项目,进行快速入门。最终项目代码如下图所示:
2.1 引入依赖
在 pom.xml 文件中,主要引入 Spring Cloud Consul Config 相关依赖。代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>labx-28</artifactId>
<groupId>cn.iocoder.springboot.labs</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>labx-28-sc-consul-config-demo</artifactId>
<properties>
<spring.boot.version>2.2.4.RELEASE</spring.boot.version>
<spring.cloud.version>Hoxton.SR1</spring.cloud.version>
</properties>
<!--
引入 Spring Boot、Spring Cloud、Spring Cloud Alibaba 三者 BOM 文件,进行依赖版本的管理,防止不兼容。
在 https://dwz.cn/mcLIfNKt 文章中,Spring Cloud Alibaba 开发团队推荐了三者的依赖关系
-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 引入 SpringMVC 相关依赖,并实现对其的自动配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 引入 Spring Cloud Consul Config 相关依赖,将 Consul 作为配置中心,并实现对其的自动配置 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>
</dependencies>
</project>
引入 spring-cloud-starter-consul-config 依赖,将 Consul 作为配置中心,并实现对它的自动配置。
2.2 配置文件
创建 bootstrap.yaml 配置文件,添加 Consul Config 配置项。配置如下:
spring:
application:
name: demo-application
cloud:
# Spring Cloud Consul 通用配置项,对应 ConsulProperties 类
consul:
host: 127.0.0.1 # Consul 主机
port: 8500 # Consul 端口
# Spring Cloud Consul Config 配置项,对应 ConsulConfigProperties 类
config:
format: YAML # Consul 配置的格式
prefix: config # Consul 配置的目录
data-key: data # Consul 配置的文件
profile-separator: ',' # 多环境目录分隔符,默认为 ,
① spring.cloud.consul
配置项,设置 Consul 客户端的配置,对应 ConsulProperties 配置类。
通过 host
和 port
配置项,设置 Consul 服务器的地址。
② spring.cloud.consul.config
配置项,设置 Consul Config 配置项,对应 ConsulConfigProperties 配置类。
通过 prefix
、data-key
、format
配置项,设置读取的 Consul 服务中的配置地址和格式。如下图所示:
- 注意,读取 Consul 服务中的配置地址是
{prefix}/{spring.application.name}/{data-key}
,因此本小节的示例是config/demo-application/data
profile-separator
配置项,多环境目录分隔符,默认为 ,
。举个例子,在我们设置 Spring Profile 为 dev
时,会多读取 Consul 服务中的配置地址是 {prefix}/{spring.application.name},dev/{data-key}
,作为配置项。
2.3 创建 Consul 配置项
打开 Consul 运维界面,创建 config/demo-application/data
配置 Key,并设置配置 Value 如下:
order:
pay-timeout-seconds: 60
create-frequency-seconds: 120
2.4 OrderProperties
创建 OrderProperties 配置类,读取 order
配置项。代码如下:
@Component
@ConfigurationProperties(prefix = "order")
public class OrderProperties {
/**
* 订单支付超时时长,单位:秒。
*/
private Integer payTimeoutSeconds;
/**
* 订单创建频率,单位:秒
*/
private Integer createFrequencySeconds;
// ... 省略 setter/getter 方法
}
① 在类上,添加 @Component
注解,保证该配置类可以作为一个 Bean 被扫描到。
② 在类上,添加 @ConfigurationProperties
注解,并设置 prefix = "order"
属性,这样它就可以读取前缀为 order
配置项,设置到配置类对应的属性上。
2.5 DemoController
创建 DemoController 类,提供测试 @ConfigurationProperties
和 @Value
注入配置的两个 HTTP 接口。代码如下:
@RestController
@RequestMapping("/demo")
public class DemoController {
@Autowired
private OrderProperties orderProperties;
/**
* 测试 @ConfigurationProperties 注解的配置属性类
*/
@GetMapping("/test01")
public OrderProperties test01() {
return orderProperties;
}
@Value(value = "${order.pay-timeout-seconds}") // @NacosValue(value = "${order.pay-timeout-seconds}")
private Integer payTimeoutSeconds;
@Value(value = "${order.create-frequency-seconds}") // @NacosValue(value = "${order.create-frequency-seconds}")
private Integer createFrequencySeconds;
/**
* 测试 @Value 注解的属性
*/
@GetMapping("/test02")
public Map<String, Object> test02() {
return new JSONObject().fluentPut("payTimeoutSeconds", payTimeoutSeconds)
.fluentPut("createFrequencySeconds", createFrequencySeconds);
}
}
2.6 DemoApplication
创建 DemoApplication 类,作为应用启动类。代码如下:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class);
}
}
2.7 简单测试
① 使用 DemoApplication 启动示例应用。在 IDEA 控制台中,可以看到 Consul 相关的日志如下:
// 加载了 Consul 服务中的配置 Key `/config/demo-application/data` 和 `/config/application/dadta`,作为配置项
2020-06-12 08:01:32.263 INFO 82286 --- [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-config/demo-application/'}, BootstrapPropertySource {name='bootstrapProperties-config/application/'}]
友情提示:Consul Config 会额外加载 Consul 服务中的配置 Key
/config/application/data
,实现多应用之间的配置共享。
② 使用浏览器,访问 http://127.0.0.1:8080/demo/test01 接口,测试 @ConfigurationProperties
注解的配置属性类,返回结果如下,符合预期:
{
"payTimeoutSeconds": 60,
"createFrequencySeconds": 120
}
② 使用浏览器,访问 http://127.0.0.1:8080/demo/test02 接口,测试 @Value
注解的属性,返回结果如下,符合预期:
{
"payTimeoutSeconds": 60,
"createFrequencySeconds": 120
}
3. 多环境配置
示例代码对应仓库:labx-28-sc-consul-config-demo。
在《芋道 Spring Boot 配置文件入门》的「6. 多环境配置」中,我们介绍如何基于 spring.profiles.active
配置项,在 Spring Boot 实现多环境的配置功能。
在本文的「2. 快速入门」小节中,我们已经提到,Spring Cloud Consul Config 在我们设置了 Spring Profile 的值时,会多读取 Consul 服务中的配置地址是 {prefix}/{spring.application.name},{spring.profiles.active}/{data-key}
,作为配置项。
下面,我们来演示 Consul Config 的多环境配置的功能。无需重新搭建,直接复用「2. 快速入门」小节的项目即可。
3.1 创建 Consul 配置项
① 创建用于 Profile 为 dev
环境的 Consul 服务中的配置地址是 config/demo-application,dev/data
,并创建 server.port
节点的值为 8081。如下图所示:
② 创建用于 Profile 为 prod
环境的 Consul 服务中的配置地址是 config/demo-application,prod/data
,并创建 server.port
节点的值为 8084。如下图所示:
这两配置都有 server.port
配置项,用于启动不同端口的服务器。