一、前言

上一节 Spring Cloud Alibaba Nacos注册中心 记录了Nacos作为注册中心的使用方式,这节继续记录下Nacos作为配置中心的使用方式。

二、框架搭建

新建一个Spring Boot项目,artifactId为spring-cloud-alibaba-nacos-config,项目的pom内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.wno704</groupId>
<artifactId>spring-cloud-alibaba-nacos-config</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Alibaba-Nacos-Config</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>1.8</java.version>
<spring-cloud-alibaba.version>2.2.3.RELEASE</spring-cloud-alibaba.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

因为这节记录的是Nacos作为配置中心的功能,所以引入的是spring-cloud-alibaba-nacos-config依赖。

三、基本使用

3.1 基本配置

在项目配置文件application.yml中添加如下配置:

1
2
3
4
5
server:
port: 8920
spring:
application:
name: config

上面配置指定应用端口为8920,应用名称为config。

接着在resources目录下新建配置文件bootstrap.yml,在里面添加如下Nacos config配置(必须在bootstrap.yml中配置,bootstrap.yml优先级比application.yml高):

1
2
3
4
5
6
spring:
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yaml

spring.cloud.nacos.config.server-addr配置了Nacos配置中心的地址,也可以通过spring.cloud.nacos.server-addr指定,它们两个是等价的;
spring.cloud.nacos.config.file-extension指定待会在Nacos配置中心读取的配置的格式为yaml格式。

3.2 nacos配置

我们回到Nacos控制台 http://localhost:8848/nacos , 在配置列表中新建一个配置:

我们新建了一个my-project.yaml配置(dataId为config.yaml,group为DEFAULT_GROUP,它们的具体含义下面会介绍到),配置了message: 'hello alibaba nacos!',创建好后,点击发布即可。

3.3 测试

接着回到我们的项目,在com.wno704.alibaba目录下新建controller包,然后在该包下新建TestController用于测试配置获取规则:

1
2
3
4
5
6
7
8
9
10
11
12
@RestController
@RefreshScope
public class TestController {

@Value("${message:null}")
private String message;

@GetMapping("message")
public String getMessage() {
return this.message;
}
}

面代码我们从刚刚在Nacos控制台配置的配置文件中获取message配置的值,@RefreshScope用于刷新配置,即我们在Nacos控制台修改了相关配置点击发布后,我们的应用能够在不重启的情况下获取到最新的配置。

启动项目,在http工具中访问: http://localhost:8920/message

配置获取成功,在Nacos控制台中将message值修改为hello nacos config!后发布,再次访问 http://localhost:8920/message

四、获取规则

Nacos配置中心通过namespace、dataId和group来唯一确定一条配置。

  • 1.namespace,即命名空间。默认的命名空间为public,我们可以在Nacos控制台中新建命名空间;
  • 2.dataId,即配置文件名称,dataId的拼接格式如下:
1
${prefix} - ${spring.profiles.active} . ${file-extension}
    • prefix默认为pring.application.name的值,也可以通过配置项spring.cloud.nacos.config.prefix来配置;
    • spring.profiles.active即为当前环境对应的profile。注意,当spring.profiles.active为空时,对应的连接符-也将不存在,dataId的拼接格式变成${prefix}.${file-extension};
    • file-extension为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension来配置。
  • 3.group,即配置分组,默认为DEFAULT_GROUP,可以通过spring.cloud.nacos.config.group配置。

所以根据这些规则,上面示例中我们的应用名称spring.application.name为config,spring.cloud.nacos.config.file-extension的值为yaml,没有指定spring.profiles.active,于是dataId为config.yaml,分组为默认的DEFAULT_GROUP,命名空间为默认的public。这就是我们在Nacos控制台中新建配置时的根据。

五、配置划分实战

Nacos配置中心的namespace、dataId和group可以方便灵活地划分配置。比如,我们现在有一个项目需要开发,项目名称为emc,项目开发人员分为两个组:GROUP_A和GROUP_B,项目分为三个环境:开发环境dev、测试环境test和生产环境prod。

假如现在GROUP_A组的组长需要在Nacos中新建一个开发环境的emc项目配置,那么他可以这样做:

5.1 创建命名空间

在Nacos控制台中新建一个名称为emc的命名空间:

新建emc命名空间后,如果增加时候,不填写命名空间id,会生成一个唯一标识该命名空间的命名空间id:6d831bba-c695-4653-83de-863aec1edcf6。

5.2 创建配置

在Nacos控制台中新建一个配置:

5.3 配置bootstrap.yml

最后在config项目的bootstrap.ymlbootstrap.yml配置文件中添加如下配置即可:

1
2
3
4
5
6
7
8
9
10
11
spring:
profiles:
active: dev
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
prefix: config
namespace: 6d831bba-c695-4653-83de-863aec1edcf6
group: GROUP_A

5.4 测试

访问 http://localhost:8920/message

六、配置回滚

Nacos中,修改配置点击发布后会创建一个对应的历史版本快照,我们可以在Nacos控制台的历史版本列表中找到这些快照:

七、获取多个配置

7.1 修改bootstrap.yml

除了通过上面的方式指定一个唯一配置外,我们还可以同时获取多个配置文件的内容,比如,将项目的bootstrap.yml内容修改为:

1
2
3
4
5
6
7
8
9
10
11
12
spring:
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
extension-configs:
- dataId: ext-config-one.yaml
group: DEFAULT_GROUP
refresh: true
- dataId: ext-config-two.yaml
group: DEFAULT_GROUP
refresh: false
  • spring.cloud.nacos.config.extension-configs[n].dataId,指定多个配置的dataId,必须包含文件格式,支持properties、yaml或yml;
  • spring.cloud.nacos.config.extension-configs[n].group,指定分组;
  • spring.cloud.nacos.config.extension-configs[n].refresh,是否支持刷新。

上面的配置中,我们分别从DEFAULT_GROUP中获取了ext-config-one.yaml和ext-config-two.yaml配置内容,并且ext-config-one.yaml支持刷新,ext-config-two.yaml不支持刷新。

注意:没有namespace的配置,言外之意就是Nacos目前还不支持多个配置指定不同的命名空间。

7.2 增加配置

我们在Nacos控制台中新建这两个配置:

ext-config-one.yaml配置内容:

ext1: 'hello'

ext-config-two.yaml配置内容:

ext2: 'world'

7.3 测试

在项目的TestController中添加:

1
2
3
4
5
6
7
8
9
    @Value("${ext1:null}")
private String ext1;
@Value("${ext2:null}")
private String ext2;

@GetMapping("multi")
public String multiConfig() {
return String.format("ext1: %s ext2: %s", ext1, ext2);
}

启动项目,http工具访问: http://localhost:8920/multi

将ext1的值修改为nice,ext2的值修改为good:
http工具访问: http://localhost:8920/multi

可以看到ext1的值更新了,ext2没有更新。

八、多配置共享

8.1 修改配置

多配置共享其实和获取多个文件配置作用差不多,下面演示下多配置共享。

将bootstrap.yml配置修改为:

1
2
3
4
5
6
spring:
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
shared-configs: ext-config-one.yaml,ext-config-two.yaml

spring.cloud.nacos.config.shared-configs指定了共享ext-config-one.yaml和ext-config-two.yaml的配置。

8.2 测试

重启项目,http工具访问: http://localhost:8920/multi

也可以正常获取。

可以看到,无论是多配置共享还是获取多个配置,要完成的事情是一样的,不过它们都有各自的局限性。多配置共享无法指定分组、无法指定命名空间、无法配置是否刷新;获取多个配置相对较为灵活,不过也不能配置命名空间。具体相关的讨论可以参考: https://github.com/alibaba/spring-cloud-alibaba/issues/141

九、常用配置

配置项key默认值说明
服务端地址spring.cloud.nacos.config.server-addr
DataId前缀spring.cloud.nacos.config.prefixspring.application.name
Groupspring.cloud.nacos.config.groupDEFAULT_GROUP
dataID后缀及内容文件格式spring.cloud.nacos.config.file-extensionpropertiesdataId的后缀,同时也是配置内容的文件格式,目前只支持 properties
配置内容的编码方式spring.cloud.nacos.config.encodeUTF-8配置的编码
获取配置的超时时间spring.cloud.nacos.config.timeout3000单位为 ms
配置的命名空间spring.cloud.nacos.config.namespace常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源隔离等。
AccessKeyspring.cloud.nacos.config.access-key
SecretKeyspring.cloud.nacos.config.secret-key
相对路径spring.cloud.nacos.config.context-path服务端 API 的相对路径
接入点spring.cloud.nacos.config.endpoint地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址
是否开启监听和自动刷新spring.cloud.nacos.config.refresh.enabledtrue

参考链接:

https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/readme-zh.md

https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html#_spring_cloud_alibaba_nacos_config