简介

Nacos除了实现了服务的注册发现之外,还将配置中心功能整合在了一起。通过Nacos的配置管理功能,我们可以将整个架构体系内的所有配置都集中在Nacos中存储。这样做的好处,在以往的教程中介绍Spring Cloud Config时也有提到,主要有以下几点:

  • 分离的多环境配置,可以更灵活的管理权限,安全性更高
  • 应用程序的打包更为纯粹,以实现一次打包,多处运行的特点

    创建配置

    第一步:进入Nacos的控制页面,在配置列表功能页面中,点击右上角的“+”按钮,进入“新建配置”页面,如下图填写内容:image.png

    创建应用

    第一步:创建一个Spring Boot应用,可以命名为:alibaba-nacos-config-client。

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.springframework.boot</groupId>
    4. <artifactId>spring-boot-starter-web</artifactId>
    5. </dependency>
    6. <dependency>
    7. <groupId>org.springframework.cloud</groupId>
    8. <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    9. </dependency>
    10. </dependencies>

    可以看到,这个例子中并没有加入nacos的服务发现模块,所以这两个内容配置中心服务发现,注册是完全可以独立使用的
    第三步:创建应用主类,并实现一个HTTP接口:

    @SpringBootApplication
    public class NacosConfigClientApplication {
    
      public static void main(String[] args) {
          SpringApplication.run(NacosConfigClientApplication.class, args);
      }
    
      @RestController
      @RefreshScope  //提供分布式的配置动态刷新
      class TestController {
    
          @Value("${nacos.config:}")
          private String config;
    
          @GetMapping("/server")
          public String hello() {
              return config;
          }
      }
    }
    

    内容非常简单,@SpringBootApplication定义是个Spring Boot应用;还定义了一个Controller,其中通过@Value注解,注入了key为nacos.config的配置(默认为空字符串),这个配置会通过/server接口返回,后续我们会通过这个接口来验证Nacos中配置的加载。另外,这里还有一个比较重要的注解@RefreshScope,主要用来让这个类下的配置内容支持动态刷新,也就是当我们的应用启动之后,修改了Nacos中的配置内容之后,这里也会马上生效。
    第四步:创建配置文件bootstrap.properties,并配置服务名称和Nacos地址 ```java spring.application.name = alibaba-nacos-config-client server.port = 9012

nacos 服务的地址

spring.cloud.nacos.config.server-addr = 127.0.0.1:8848

服务区分

spring.profiles.active = dev

![image.png](https://cdn.nlark.com/yuque/0/2021/png/514731/1624953706050-a8f37ef5-b8f0-4338-888d-c8c3cb36b20b.png#clientId=u39f13da7-4207-4&from=paste&height=540&id=uc6bf5fdf&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1080&originWidth=1920&originalType=binary&ratio=2&size=513374&status=done&style=none&taskId=u55de034a-bcec-4936-892c-eeed33d01bb&width=960)<br />**注意**:这里必须使用bootstrap.properties。同时,spring.application.name值必须与上一阶段Nacos中创建的配置Data Id匹配(除了.properties或者.yaml后缀);<br />DataId匹配规则为 ${prefix}-${spring.profiles.active}.${file-extension} ;<br />${prefix}默认为应用名称,active若为空则不拼接 -dev, ${file-extension}默认为properties<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/514731/1624954025267-204f9137-7eed-4e14-932f-7e94344cdccc.png#clientId=u39f13da7-4207-4&from=paste&height=207&id=u8075182f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=413&originWidth=1588&originalType=binary&ratio=2&size=48353&status=done&style=none&taskId=u048aeafe-f637-4588-977b-e342e84c737&width=794)<br />**第五步**:启动上面创建的应用。![image.png](https://cdn.nlark.com/yuque/0/2021/png/514731/1624953484831-4b7117d8-1e34-426b-8c46-363c53491339.png#clientId=u39f13da7-4207-4&from=paste&height=58&id=u740ea5d6&margin=%5Bobject%20Object%5D&name=image.png&originHeight=115&originWidth=1706&originalType=binary&ratio=2&size=28773&status=done&style=none&taskId=u7c98e3fd-00a8-4e30-98b1-1c47de4d7f0&width=853)<br />在启动的时候,我们可以看到类似上面的日志信息,这里会输出应用程序要从Nacos中获取配置的dataId和group。如果在启动之后,发现配置信息没有获取到的时候,可以先从这里着手,看看配置加载的目标是否正确。<br />**第六步**:验证配置获取和验证动态刷新<br />,访问接口: localhost:9012/server,一切正常的话,将返回Nacos中配置的spring-cloud-alibaba-learning。然后,再通过Nacos页面,修改这个内容,点击发布之后,再访问接口,可以看到返回结果变了。<br />同时,在应用的客户端,我们还能看到如下日志:![image.png](https://cdn.nlark.com/yuque/0/2021/png/514731/1624953546735-3e1dc142-5bd0-4103-95f9-c03f19fe8c84.png#clientId=u39f13da7-4207-4&from=paste&height=27&id=u2ca6b632&margin=%5Bobject%20Object%5D&name=image.png&originHeight=53&originWidth=1005&originalType=binary&ratio=2&size=8877&status=done&style=none&taskId=u6215f2be-cbd9-4241-b0a6-2a0951214b4&width=502.5)<br />在Nacos中修改了Key,在用到这个配置的应用中,也自动刷新了这个配置信息。

<a name="HBzaf"></a>
## Nacos配置的多文件加载与共享配置
<a name="pgxAS"></a>
### 加载多个配置
通过之前的学习,我们已经知道Spring应用对Nacos中配置内容的对应关系是通过下面三个参数控制的:

- spring.cloud.nacos.config.prefix
- spring.cloud.nacos.config.file-extension
- spring.cloud.nacos.config.group

默认情况下,会加载Data ID=${spring.application.name}.properties,Group=DEFAULT_GROUP的配置。<br />假设现在有这样的一个需求:我们想要对所有应用的Actuator模块以及日志输出做统一的配置管理。所以,我们希望可以将Actuator模块的配置放在独立的配置文件actuator.properties文件中,而对于日志输出的配置放在独立的配置文件log.properties文件中。通过拆分这两类配置内容,希望可以做到配置的共享加载与统一管理。<br />这时候,我们只需要做以下两步,就可以实现这个需求:<br />**第一步**:在Nacos中创建Data ID=actuator.properties,Group=DEFAULT_GROUP和Data ID=log.properties,Group=DEFAULT_GROUP的配置内容。<br />[![](https://cdn.nlark.com/yuque/0/2021/png/514731/1624955089925-12ad4954-2034-4849-8b9a-95c2c47e0369.png#clientId=u09ab86ca-e8f2-4&from=paste&id=u787a0a2f&margin=%5Bobject%20Object%5D&originHeight=272&originWidth=1131&originalType=url&ratio=2&status=done&style=none&taskId=ua8d57379-5ac2-43a3-ae18-018c65d8513)](https://blog.didispace.com/images/pasted-153.png)<br />**第二步**:在Spring Cloud应用中通过使用spring.cloud.nacos.config.ext-config参数来配置要加载的这两个配置内容,比如:
```java
spring.cloud.nacos.config.ext-config[0].data-id=actuator.properties
spring.cloud.nacos.config.ext-config[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.ext-config[0].refresh=true
spring.cloud.nacos.config.ext-config[1].data-id=log.properties
spring.cloud.nacos.config.ext-config[1].group=DEFAULT_GROUP
spring.cloud.nacos.config.ext-config[1].refresh=true

可以看到,spring.cloud.nacos.config.ext-config配置是一个数组List类型。每个配置中包含三个参数:data-id、group,refresh;前两个不做赘述,与Nacos中创建的配置相互对应,refresh参数控制这个配置文件中的内容时候支持自动刷新,默认情况下,只有默认加载的配置才会自动刷新,对于这些扩展的配置加载内容需要配置该设置时候才会实现自动刷新。

共享配置

通过上面加载多个配置的实现,实际上我们已经可以实现不同应用共享配置了。但是Nacos中还提供了另外一个便捷的配置方式,比如下面的设置与上面使用的配置内容是等价的:

spring.cloud.nacos.config.shared-dataids=actuator.properties,log.properties
spring.cloud.nacos.config.refreshable-dataids=actuator.properties,log.properties
  • spring.cloud.nacos.config.shared-dataids参数用来配置多个共享配置的Data Id,多个的时候用用逗号分隔
  • spring.cloud.nacos.config.refreshable-dataids参数用来定义哪些共享配置的Data Id在配置变化时,应用中可以动态刷新,多个Data Id之间用逗号隔开。如果没有明确配置,默认情况下所有共享配置都不支持动态刷新

    配置加载的优先级

    当我们加载多个配置的时候,如果存在相同的key时,我们需要深入了解配置加载的优先级关系。
    在使用Nacos配置的时候,主要有以下三类配置:

  • A: 通过spring.cloud.nacos.config.shared-dataids定义的共享配置

  • B: 通过spring.cloud.nacos.config.ext-config[n]定义的加载配置
  • C: 通过内部规则(spring.cloud.nacos.config.prefix、spring.cloud.nacos.config.file-extension、spring.cloud.nacos.config.group这几个参数)拼接出来的配置

要弄清楚这几个配置加载的顺序,我们从日志中也可以很清晰的看到,我们可以做一个简单的实验:

spring.cloud.nacos.config.ext-config[0].data-id=actuator.properties
spring.cloud.nacos.config.ext-config[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.ext-config[0].refresh=true

spring.cloud.nacos.config.shared-dataids=log.properties
spring.cloud.nacos.config.refreshable-dataids=log.properties

根据上面的配置,应用分别会去加载三类不同的配置文件,启动应用的时候,将会在日志中看到如下输出:

2019-02-08 21:23:02.665  INFO 63804 --- [main] o.s.c.a.n.c.NacosPropertySourceBuilder   : Loading nacos data, dataId: 'log.properties', group: 'DEFAULT_GROUP'
2019-02-08 21:23:02.671  INFO 63804 --- [main] o.s.c.a.n.c.NacosPropertySourceBuilder   : Loading nacos data, dataId: 'actuator.properties', group: 'DEFAULT_GROUP'
2019-02-08 21:23:02.677  INFO 63804 --- [main] o.s.c.a.n.c.NacosPropertySourceBuilder   : Loading nacos data, dataId: 'alibaba-nacos-config-client.properties', group: 'DEFAULT_GROUP'

后面加载的配置会覆盖之前加载的配置,所以优先级关系是:A < B < C