Skip to content
On this page

Nacos Config

官方github文档:Nacos config · alibaba/spring-cloud-alibaba Wiki · GitHub

Nacos提供用于存储配置和其他元数据的key/value存储,为分布式系统中外部化配置提供服务器端和客户端支持,使用Spring Cloud Alibaba Nacos Config。我们可以在Nacos Server 集群中管理我们服务的外部属性配置

市面配置文件管理组件

  • spring cloud config
  • apollo
  • nacos

与Spring Cloud Config对比

  1. springcloud config大部分场景结合git 使用, 动态变更还需要依赖Spring Cloud Bus 消息总线来通过所有的客户端变化.
  2. springcloud config不提供可视化界面
  3. nacos config使用长轮询更新配置, 一旦配置有变动后,通知Provider的过程非常的迅速, 从速度上优于springcloud

快速集成Nacos Config

服务端

  1. 配置管理->配置列表->新建

image-20220716162824863

  1. 新建的内容如下图:
  • Data ID:alibaba-order.properties
  • Group:DEFAULT_GROUP
  • 配置格式选取Properties
  • 配置内容
user.name=nacos-config-properties
user.age=90
  • 注意dataid是以 properties(默认的文件扩展名方式)为扩展名

image-20220716162758278

客户端

  1. 引入依赖
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
  1. 启动类增加输出查看效果
java
public static void main(String[] args) {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(OrderApplication.class, args);
        String userName = applicationContext.getEnvironment().getProperty("user.name");
        String userAge = applicationContext.getEnvironment().getProperty("user.age");
        System.err.println("user name :"+userName+"; age: "+userAge);
    }
  1. bootstrap.yml增加nacos config配置,配置如下图所示【必须是bootstrap.yml,不能是application.yml】

image-20220716163155739

  1. 启动项目,查看效果

image-20220716163331725

  1. 启动过程报错
[SecurityProxy] login http request failed url: http://192.168.1.6:9020/nacos/v1/auth/users/login, params: {username=naocs}, bodyMap: {password=nacos}, errorMsg: errCode: 100, errMsg: Nacos serialize for class [com.alibaba.nacos.common.http.HttpRestResult] failed.

解决方式:

nginx配置文件的http模块增加9020端口的监听代理

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;

    keepalive_timeout  65;

    #gzip  on;

       upstream nacoscluster {
        server 127.0.0.1:8849;
        server 127.0.0.1:8851;
        server 127.0.0.1:8853;
         }

    server {
        listen       8848;
        server_name  localhost;
        location /nacos/ {
            proxy_pass http://nacoscluster/nacos/;
       }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

    server {
        listen       9020;
        server_name  localhost;
        location /nacos/ {
            proxy_pass http://nacoscluster/nacos/;
       }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

基于 dataid 为 yaml 的文件扩展名配置方式

服务端

新建一个配置,配置内容如下图所示:

image-20220716170920444

客户端

  1. bootstrap.yml配置文件增加文件后缀配置:spring.cloud.nacos.config.file-extension=yaml

  2. 重启项目:

image-20220716171015597

支持配置的动态更新

客户端

  1. 修改启动类,循环监听
java
public static void main(String[] args) throws InterruptedException {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(OrderApplication.class, args);
        while(true) {
            //当动态配置刷新时,会更新到 Enviroment中,因此这里每隔一秒中从Enviroment中获取配置
            String userName = applicationContext.getEnvironment().getProperty("user.name");
            String userAge = applicationContext.getEnvironment().getProperty("user.age");
            System.err.println("user name :" + userName + "; age: " + userAge);
            TimeUnit.SECONDS.sleep(1);
        }
    }

服务端

  1. 修改alibaba-order.yaml中的配置内容,后回到客户端看控制台打印效果
  • 注意:可以通过配置 spring.cloud.nacos.config.refresh.enabled=false 来关闭动态刷新

可支持profile粒度的配置

spring-cloud-starter-alibaba-nacos-config 在加载配置的时候,不仅仅加载了以 dataid 为 ${spring.application.name}.${file-extension:properties} 为前缀的基础配置,还加载了dataid为 ${spring.application.name}-${profile}.${file-extension:properties} 的基础配置。在日常开发中如果遇到多套环境下的不同配置,可以通过Spring 提供的 ${spring.profiles.active} 这个配置项来配置。

服务端

  1. 分别新建两个(alibaba-order-dev.yaml、alibaba-order-prod.yaml)配置,内容如下:

image-20220716172640900

image-20220716172614842

客户端

  1. 增加spring.profiles.active=dev 的配置
    • 必须放在 bootstrap.properties 文件中

image-20220716172820346

  • spring.profiles.active=dev 则读取服务端的alibaba-order-dev.yaml配置
  • spring.profiles.active=prod 则读取服务端的alibaba-order-prod.yaml配置

注意

spring.profiles.active=<profilename>可以写死在配置文件中来指定读取对应的配置文件,而在真正的项目实施过程中这个变量的值是需要不同环境而有不同的值。这时我们可以通过 -Dspring.profiles.active=<profile> 参数指定其配置来达到环境间灵活的切换。

NameSpace、Group、DataId区别

  • namespace:代表不同环境,如开发、测试、生产环境
  • Group:代表某个项目,如人力系统、物流系统
  • DataId:每个项目下往往有若干个工程(微服务),每个配置级(DataId)是一个工程(微服务)的主配置文件
  • namespace默认是空串,公共命名空间(public),分组默认是DEFAULT_GROUP

image-20220716173548045

Namespace配置

用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。

在没有明确指定 ${spring.cloud.nacos.config.namespace} 配置的情况下, 默认使用的是 Nacos 上 Public 这个namespae。如果需要使用自定义的命名空间,可以通过以下配置来实现:spring.cloud.nacos.config.namespace=dev[dev为创建命名空间输入的ID值]

image-20220716172103256

注意:

该配置必须放在 bootstrap.yml文件中。此外 spring.cloud.nacos.config.namespace 的值是 namespace 对应的 id,id 值可以在 Nacos 的控制台获取。并且在添加配置时注意不要选择其他的 namespae,否则将会导致读取不到正确的配置。

Group配置

在没有明确指定 ${spring.cloud.nacos.config.group} 配置的情况下, 默认使用的是 DEFAULT_GROUP 。如果需要自定义自己的 Group,可以通过以下配置来实现:spring.cloud.nacos.config.group=DEVELOP_GROUP

注意:

该配置必须放在 bootstrap.yml文件中。并且在添加配置时 Group 的值一定要和 spring.cloud.nacos.config.group 的配置值一致。

DataId配置

DataId是组织划分配置的维度之一,DataId通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称所标识。DataId通常采用类Java包(如:com.huangjiliang.order)的命名规则保证全局唯一性,此命名规则非强制

spring.application.name=alibaba-order
spring.cloud.nacos.config.server-addr=192.168.1.6:8848

# config external configuration
# 1、Data Id 在默认的组 DEFAULT_GROUP,不支持配置的动态刷新
spring.cloud.nacos.config.extension-configs[0].data-id=ext-config-common01.properties

# 2、Data Id 不在默认的组,不支持动态刷新
spring.cloud.nacos.config.extension-configs[1].data-id=ext-config-common02.properties
spring.cloud.nacos.config.extension-configs[1].group=GLOBALE_GROUP

# 3、Data Id 既不在默认的组,也支持动态刷新
spring.cloud.nacos.config.extension-configs[2].data-id=ext-config-common03.properties
spring.cloud.nacos.config.extension-configs[2].group=REFRESH_GROUP
spring.cloud.nacos.config.extension-configs[2].refresh=true
  • 通过 spring.cloud.nacos.config.extension-configs[n].data-id 的配置方式来支持多个 Data Id 的配置。
  • 通过 spring.cloud.nacos.config.extension-configs[n].group 的配置方式自定义 Data Id 所在的组,不明确配置的话,默认是 DEFAULT_GROUP
  • 通过 spring.cloud.nacos.config.extension-configs[n].refresh 的配置方式来控制该 Data Id 在配置变更时,是否支持应用中可动态刷新, 感知到最新的配置值。默认是不支持的。
  • 多个 Data Id 同时配置时,他的优先级关系是 spring.cloud.nacos.config.extension-configs[n].data-id 其中 n 的值越大,优先级越高
  • spring.cloud.nacos.config.extension-configs[n].data-id 的值必须带文件扩展名,文件扩展名既可支持 properties,又可以支持 yaml/yml。 此时 spring.cloud.nacos.config.file-extension 的配置对自定义扩展配置的 Data Id 文件扩展名没有影响。
# 配置支持共享的 Data Id
spring.cloud.nacos.config.shared-configs[0].data-id=common.yaml

# 配置 Data Id 所在分组,缺省默认 DEFAULT_GROUP
spring.cloud.nacos.config.shared-configs[0].group=GROUP_APP1

# 配置Data Id 在配置变更时,是否动态刷新,缺省默认 false
spring.cloud.nacos.config.shared-configs[0].refresh=true
  • 通过 spring.cloud.nacos.config.shared-configs[n].data-id 来支持多个共享 Data Id 的配置
  • 通过 spring.cloud.nacos.config.shared-configs[n].group 来配置自定义 Data Id 所在的组,不明确配置的话,默认是 DEFAULT_GROUP。
  • 通过 spring.cloud.nacos.config.shared-configs[n].refresh 来控制该Data Id在配置变更时,是否支持应用中动态刷新,默认false。

配置的优先级

Spring Cloud Alibaba Nacos Config 目前提供了三种配置能力从 Nacos 拉取相关的配置。

  • A: 通过 spring.cloud.nacos.config.shared-configs[n].data-id 支持多个共享 Data Id 的配置
  • B: 通过 spring.cloud.nacos.config.extension-configs[n].data-id 的方式支持多个扩展 Data Id 的配置
  • C: 通过内部相关规则(应用名+ Profile )自动生成相关的 Data Id 配置

当三种方式共同使用时,他们的一个优先级关系是:A < B < C

@RefreshScope

@Value注解可以获取到配置中心的值,但是无法动态感知修改后的值,需要利用@RefreshScope注解

java
@RestController
@RequestMapping("order")
@RefreshScope
public class OrderMsgController {

    @Value("${user.name}")
    private String username;

    @GetMapping("getYamlValue")
    public void getYamlValue() {
        System.out.println("username:" + username);
    }

}

完全关闭配置

通过设置 spring.cloud.nacos.config.enabled = false 来完全关闭 Spring Cloud Nacos Config