在前面的教程中已经介绍了Nacos的服务注册与发现功能,而Nacos提供的另一个重要功能就是统一配置。在单机应用中,统一化配置并不是那么重要,但是在微服务环境中统一化配置就很重要了。如果现在需要改一个服务的配置,而该服务由多个相同服务的应用提供,那么我们则需要将每个服务中的配置都修改一遍,这显然在服务越多的情况下越麻烦,这也就是统一配置存在的意义了。统一配置通过集中管理配置,并提供配置刷新等功能让配置需要变更时更加方便和高效。
快速开始
还是老样子,在之前的父工程中创建新的子模块nacos-config
。该模块中需要引入以下依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
如果使用的spring-cloud-alibaba
版本是2021.1
还需要引入以下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.1.1</version>
</dependency>
我们的spring-cloud-alibaba
版本正好是2021.1
所以我们同样也需要引入该配置,最后的pom依赖如下:
<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>spring-cloud-alibaba-demo</artifactId>
<groupId>com.zc</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>nacos-config</artifactId>
<packaging>jar</packaging>
<name>nacos-config</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
要使用Nacos的配置功能,首先我们需要在应用的resource
目录下创建配置文件bootstrap.yml
,其内容如下:
spring:
application:
name: nacos-config
cloud:
nacos:
config:
server-addr: 192.168.1.11:8848,192.168.1.11:8850,192.168.1.11:8852
username: nacos
password: nacos
file-extension: yaml
通常情况下我们是通过application.yml来写配置文件,而bootstrap.yml则是用来配置引导上下文的,通过这种方式我们可以将引导程序和主上下文的配置分开。
Spring Cloud应用程序通过创建引导上下文来运行,该上下文是主应用程序的父上下文。它负责从外部加载配置属性,并负责解密本地外部属性配置文件中的属性。这两个上下文共享一个环境,这也是任何Spring应用程序的外部属性的来源。引导属性(不是指引导文件中的属性)以高优先级添加,因此本地配置无法覆盖它们。
关于引导上下文这部分内容,可以参考官方文档:
https://cloud.spring.io/spring-cloud-commons/multi/multi__spring_cloud_context_application_context_services.html
接下来我们在nacos管理后台中创建配置,其中Data ID
就是我们的应用名称nacos-config.yaml
,Group
为默认值DEFAULT_GROUP
,最后配置文件格式选择YAML
,其内容如下:
student:
name: mac
最后我们通过一个接口来获取配置内容:
@RestController
public class StudentController {
@Value("${student.name}")
private String name;
@GetMapping("student")
public String student() {
return String.format("name => [%s]", name);
}
}
启动应用最后通过localhost:${port}/student
获取的内容如下:
name => [mac]
从结果可以看出name
就是我们在Nacos中配置值。
刷新配置
通过上面一个例子我们知道了统一化配置,接下来就是另一个特性刷新配置。通常我们在修改配置时需要重启应用配置才能生效,在微服务环境下显然不太可能,所以就需要动态刷新配置了。我们还是基于前面的示例代码,创建一个配置类:
@Data
@RefreshScope
@ConfigurationProperties(prefix = "student")
public class Student {
private String name;
private Integer age;
private String classNo;
private String className;
}
这个与我们平常在SpringBoot中使用的配置来说没啥太大区别,唯一的不同是增加了一个@RefreshScope
,它是SpringCloud环境下提供的一个scope,通过它可以实现刷新Bean的功能。最后不要忘记增加@ConfigurationPropertiesScan
或者@EnableConfigurationProperties
来使刚才的配置类生效。同时在StudentController
增加如下内容:
@Resource
private Student student;
@GetMapping("student_refresh")
public String studentRefresh(){
return student.toString();
}
我们再次启动服务,初次访问localhost:${port}/student_refresh
得到如下内容:
Student(name=mac, age=null, classNo=null, className=null)
接下来通过Nacos后台界面修改内容如下:
student:
name: tom
age: 18
再次访问链接得到如下内容:
Student(name=tom, age=18, classNo=null, className=null)
从结果可以看出,刚刚在Nacos后台修改的配置即使应用不重启也刷新生效了。
配置Data Id
默认Data Id
在先前的示例中,我们在Nacos中填写的Data Id
格式为${spring.application.name}.${file-extension}
,如果我们不填写后面的file-extension
也是可以的,但是Nacos管理后台中选择的配置格式必须跟bootstrap.yml
中spring.cloud.nacos.config.file-extension
保持一致。
也就是说我们可以将之前的配置文件名nacos-config.yaml
修改为nacos-config
。
基于Profile粒度配置
在实际开发中我们可能根据环境来应用配置文件。例如在开发环境中,我们创建配置文件application-dev.yml
,而在测试环境中我们使用application-test.yml
,而最后通过spring.profiles.active
应用哪一个配置文件。同样,在Nacos中也支持该特性,它可以根据profile的值来应用对应的配置文件。它的应用格式如下:
${spring.application.name}-${profile}.${file-extension}
现在我们创建两个配置文件nacos-config-dev.yaml
和nacos-config-test.yaml
,其内容分别如下:
student:
class-no: dev
student:
class-no: test
接下来我们在bootstrap.yml中增加如下配置:
spring:
profiles:
active: dev
接下来重新启动应用,再次访问localhost:${port}/student_refresh
,得到结果如下:
Student(name=tom, age=18, classNo=dev, className=null)
从结果可以看出,配置文件nacos-config.yaml
和nacos-config-dev.yaml
都生效了,关于属性值覆盖稍后再讲解。
自定义Data Id配置
通过上面我们已经知道了默认Data Id和基于profile的Data Id,同时还支持自定义Data Id配置。接下来我们在Nacos管理后台创建Data Id
为nacos-config-extension-configs-1.yaml
的配置,配置内容如下:
student:
class-name: nacos-config-extension-configs-1.yam
在bootstrap.yml
文件中增加如下配置:
spring:
application:
name: nacos-config
cloud:
nacos:
config:
extension-configs:
- data-id: nacos-config-extension-configs-1.yaml
同时它还支持另外两个属性group
和refresh
,默认情况下refresh
为false,也就是不支持动态刷新。需要注意的是,extension-configs
是一个数组,它支持配置多个。
该方式最后的
file-extension
不能省略。
同样Nacos还支持另外一种方式来自定义配置文件,extension-configs
通常用在同一应用不同实例共享配置,而shared-configs
则用在不同应用共享同一配置。例如在order
和store
服务中,不同的order
实例使用extension-configs
来共享配置,而order
和store
不同应用通过shared-configs
来共享配置。
在Nacos后台中创建nacos-config-shared-configs-1.yaml
配置文件,其配置内容如下:
student:
ext-pro: nacos-config-shared-configs-1.yaml男
在bootstrap.yml
文件中增加如下配置:
spring:
application:
name: nacos-config
cloud:
nacos:
config:
shared-configs:
- data-id: nacos-config-shared-configs-1.yaml
最后在Student
类中增加extPro
属性,重启应用再次刷新链接得到如下内容:
Student(name=tom, age=18, classNo=dev, className=nacos-config-extension-configs-1.yam, extPro=nacos-config-shared-configs-1.yaml)
属性值覆盖问题
前面介绍了Nacos各种配置文件的配置方式,但是存在一个问题就是不同的配置文件中可能会存在相同的配置,那么这些配置哪个会生效呢?下面我们通过以下几种情况来分析。
远程加载配置和本地application.yml
首先我们删除Nacos后台的所有配置文件,然后创建配置文件nacos-config.yaml
,其内容如下:
student:
name: tom
age: 18
然后在本地应用中创建配置文件其内容如下:
student:
name: tom
age: 18
class-no: c2
class-name: 二班
ext-pro: 扩展
最后运行结果如下:
Student(name=tom, age=18, classNo=c2, className=二班, extPro=扩展)
通过结果可以发现,通过远程加载的配置文件其属性值会覆盖本地application.yml中的配置属性值。
默认Data Id
默认情况下支持三种属性配置文件,它们分别为:
-
${spring.application.name}
,例如nacos-config -
${spring.application.name}.${file-extension}
,例如nacos-config.yaml -
${spring.application.name}-${profile}.${file-extension}
,例如nacos-config-dev.yaml
对于上面三种配置文件,其优先级根据上面的顺序越来越高。其实这一点可以通过源码看出,其源码位于NacosPropertySourceLocator
中:
private void loadApplicationConfiguration(
CompositePropertySource compositePropertySource, String dataIdPrefix,
NacosConfigProperties properties, Environment environment) {
String fileExtension = properties.getFileExtension();
String nacosGroup = properties.getGroup();
// load directly once by default
loadNacosDataIfPresent(compositePropertySource, dataIdPrefix, nacosGroup,
fileExtension, true);
// load with suffix, which have a higher priority than the default
loadNacosDataIfPresent(compositePropertySource,
dataIdPrefix + DOT + fileExtension, nacosGroup, fileExtension, true);
// Loaded with profile, which have a higher priority than the suffix
for (String profile : environment.getActiveProfiles()) {
String dataId = dataIdPrefix + SEP1 + profile + DOT + fileExtension;
loadNacosDataIfPresent(compositePropertySource, dataId, nacosGroup,
fileExtension, true);
}
}
从源码已经其中的注释可以看出,其优先级就是顺序就是profile最高,接着就是指定了file-extension的,最后就是默认的。
自定义Data Id配置
对于通过shared-configs
和extension-configs
加载的配置文件,其优先级要低于约定的Data Id的配置,也就是通过应用名+profile自动加载的配置文件。
而shared-configs
的优先级则低于extension-configs
。
对于自定义的Data Id配置,它们都支持同时配置多个。对于同一类型的多个,如果是通过properties
方式配置的,例如:
spring.cloud.nacos.config.shared-configs[0].data-id=common-0.yaml
spring.cloud.nacos.config.shared-configs[1].data-id=common-1.yaml
其中shared-configs[n]
的n越大,其优先级越高。而对于像yaml
这样的配置,越排在后面的配置其优先级越高。例如下面的配置:
spring:
application:
name: nacos-config
cloud:
nacos:
config:
extension-configs:
- data-id: nacos-config-extension-configs-1.yaml
- data-id: nacos-config-extension-configs-2.yaml
其中nacos-config-extension-configs-2.yaml
优先级大于nacos-config-extension-configs-1.yaml
。
小结
以上就是使用Nacos作为统一配置中心的所有示例了。如果有部分不太清楚的部分可以通github官方wiki查看相关内容,其文档地址如下:
https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config
本文的示例工程代码地址:
https://github.com/I-Like-Pepsi/spring-cloud-alibaba-demo
往期相关文章:
Spring Cloud Alibaba版本教程-Nacos服务注册和发现
原文始发于微信公众号(一只菜鸟程序员):SpringCloud Alibaba版本教程-Nacos统一配置
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/72788.html