图文详述Nacos配置中心使用:应用间配置共享、扩展配置文件加载优先级、新老版本差异

简介: 图文详述Nacos配置中心使用:应用间配置共享、扩展配置文件加载优先级、新老版本差异

一、前言

项目上使用Nacos做为配置中心,以前使用的是Concul;现在准备详细梳理一下Nacos做为配置中心的配置文件加载优先级问题,因为以前在使用Consul的时候,由于配置文件优先级问题踩过大坑。

二、实战

1、集成Nacos配置中心

1) POM中引入SpringCloud、Spring Cloud Alibaba依赖,记得做好maven版本管理、否则存在版本问题一地鸡毛的场景。

<properties>
    <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>

<dependencies>
    <!--整合nacos config-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!--整合spring cloud-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR8</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!--整合spring cloud alibaba-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.2.5.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

2) 在bootstrap.yml中配置Nacos-server的地址

server:
  port: 9001

spring:
  application:
    name: config1 # 配置名,即Nacos dashboard中的Data id
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848 # 配置中心地址,集群的话多个节点使用,分隔
        file-extension: yaml # 配置的后缀名
        namespace: 2c38da96-f654-4105-bbc0-63befaa449f0 # 命名空间ID
        group: DEFAULT_GROUP # 指定要获取配置的组

在这里插入图片描述
3) 随便写个Controller,用@Value等注解或ConfigurableApplicationContext获取配置信息。

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author zhouxin
 * @RefreshScope 动态加载配置
 **/
@RefreshScope
@RestController
public class NacosServerController {

    @Resource
    private ConfigurableApplicationContext configurableApplicationContext;

    /**
     * 可用于验证本服务配置文件和extension-configs之间的优先级
     */
    @Value("${student.name:null}")
    private String name;

    /**
     * 如果只是通过@Value获得的配置信息,不会随着Nacos的修改操作而获得最新配置信息。那么,实时获取最新配置信息有两种方式:
     * 方式1:添加@RefreshScope注解。
     * 方式2:通过getProperty的方式,获得最新的配置信息。
     *
     * @return
     */
    @GetMapping("/name")
    public String getName() {
        String name1 = configurableApplicationContext.getEnvironment().getProperty("student.name");
        return String.format("name=%s <br> name1=%s", name, name1);
    }

Nacos服务端config1.yaml配置如下:
在这里插入图片描述
启动服务,通过HTTP访问(http://localhost:9001/name)到的结果如下:
在这里插入图片描述
这说明:我们可以通过很多中方式注入配置,包括:@Value、@ConfigurationProperties、ConfigurableApplicationContext等。

2、应用配置共享

Nacos提供两种应用间共享配置的方式:扩展DataId(extension-configs)、共享DataId(shared-configs);另外需共享的DataId,yaml后缀不能少,且目前只支持yaml/properties。

0)Nacos服务端配置准备

(1)config1.yaml

在这里插入图片描述

(2)config2.yaml

在这里插入图片描述

(3)config3.yaml在这里插入图片描述

(4)config4.yaml

在这里插入图片描述

(5)config5.yaml

在这里插入图片描述

1)扩展Data Id配置

Spring Cloud Alibaba Nacos Config 从 0.2.1 版本后,可支持自定义扩展Data Id 配置,特性如下:

1、支持多个 Data Id 的配置;

通过 spring.cloud.nacos.config.extension-configs[n].data-id 的配置方式

2、可以自定义Data Id 所在的组,不明确配置的话,默认是 DEFAULT_GROUP;

通过 spring.cloud.nacos.config.extension-configs[n].group 的配置方式

3、当某个Data Id 的配置变更时,自定义应用中是否动态刷新配置值,默认为否;

通过 spring.cloud.nacos.config.extension-configs[n].refresh 的配置方式

源码中的体现:

(1)在bootstrap.yml文件中按住command 鼠标左键点extension-configs,进入如下源码:
在这里插入图片描述
从上面我们可以看出扩展DataID的主体是Config类,我们看一下它:
在这里插入图片描述
从这里我们便能看出上面提到的extension-configs的特性和一些默认值。

使用:

(1)bootstrap.yml文件中增加如下配置:

spring:
  cloud:
    nacos:
      config:
        # 使用extension-configs[n],配置加载多个dataId
        extension-configs:
          - data-id: config4.yaml
            group: CONFIG4_GROUP
            refresh: true  # 动态刷新配置
          - data-id: config5.yaml
            group: DEFAULT_GROUP
            refresh: true  # 动态刷新配置

(2)controller中引入只存在于config4.yaml和config5.yaml中的配置:

@Value("${config4.name:null}")
private String config4Name;

@Value("${config5.name:null}")
private String config5Name;

@GetMapping("/allname")
public String getAllName() {
    return String.format("config4Name=%s <br> config5Name=%s", config4Name, config5Name);
}

通过HTTP访问(http://localhost:9001/allname)到的结果如下:
在这里插入图片描述

2)共享Data Id配置

为了更加清晰的在多个应用间配置共享的 Data Id ,也可以通过以下的方式来配置:

1、支持多个 Data Id 的配置;

通过 spring.cloud.nacos.config.shared-configs[n].data-id 的配置方式

2、可以自定义Data Id 所在的组,不明确配置的话,默认是 DEFAULT_GROUP;

通过 spring.cloud.nacos.config.shared-configs[n].group 的配置方式

3、当某个Data Id 的配置变更时,自定义应用中是否动态刷新配置值,默认为否;

通过 spring.cloud.nacos.config.shared-configs[n].refresh 的配置方式

使用:

(1)bootstrap.yml文件中增加如下配置:

spring:
  cloud:
    nacos:
      config:
        # 使用shared-config[n],配置加载多个dataId
        shared-configs:
          - data-id: config2.yaml
            group: DEFAULT_GROUP
            refresh: true  # 动态刷新配置
          - data-id: config3.yaml
            group: DEFAULT_GROUP
            refresh: true  # 动态刷新配置

(2)controller中引入只存在于config2.yaml和config3.yaml中的配置:

@Value("${config2.name:null}")
private String config2Name;

@Value("${config3.name:null}")
private String config3Name;

@GetMapping("/allname")
public String getAllName() {
    return String.format("config2Name=%s <br> config3Name=%s", config2Name, config3Name);
}

通过HTTP访问(http://localhost:9001/allname)到的结果如下:
在这里插入图片描述

聪明的大家肯定发现这和extension-configs扩展DataId的方式一毛一样啊,是的,它就一毛一样。
但是注意,在老版本中它俩的扩展方式还真不一样,下面我们来看一下新老版本扩展/共享DataId的差异?

3、扩展/共享DataId新老版本差异

1)老版本的pom

<properties>
    <java.version>1.8</java.version>
    <spring.boot>2.1.3.RELEASE</spring.boot>
    <spring.cloud>Greenwich.RELEASE</spring.cloud>
    <spring.cloud.alibaba>2.1.0.RELEASE</spring.cloud.alibaba>
</properties>

<dependencyManagement>
<dependencies>
    <!-- 引入Spring Cloud Alibaba依赖 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-dependencies</artifactId>
        <version>${spring.cloud.alibaba}</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
    <!-- 引入Spring Cloud依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring.cloud}</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
    <!-- 引入Spring Boot依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>${spring.boot}</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
</dependencies>
</dependencyManagement>

2)扩展DataId方式的差异

新版本yaml中使用extension-configs,老版本yaml使用ext-config;除此之外,功能上并没有区别。
在这里插入图片描述

3)分享DataId方式的差异

(1)使用上:

1、新版本yaml中使用 shared-configs
2、老版本yaml使用 shared-dataids根据DataID加载配置信息、使用 refreshable-dataids实现指定DataId配置信息的动态刷新;

2)功能上:

新版本yaml中支持指定group,老版本中不支持指定Group,只会取默认的group-- DEFAULT_GROUP

在这里插入图片描述
为什么老版本不支持指定group呢?我们来看一下:

3)源码分析

(1) 在bootstrap.yml文件中按住command 鼠标左键点shared-dataids,进入如下源码:
在这里插入图片描述

public static final String SEPARATOR = "[,]";

这里我们可以看到它会将传入的sharedDataids以,分隔为多个DataId,并将DataId作为入参构造Config:
在这里插入图片描述
其中只会指定dataId,并不会牵扯到group。

(2) 我们再看shared-dataids
在这里插入图片描述
在这里插入图片描述
它也只是将拆分出的所有dataId对应的Config的refresh属性设置为true,也不牵扯到group。

(3)会不会有group-dataids呢?
进入NacosConfigProperties类中全局搜索一把,并没有。

好了,新老版本的差异我们也聊完了,下面看一下配置文件加载的优先级吧。

4、扩展的配置文件加载优先级

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

(1)以老版本来说:

1、shared-dataids中越靠后,优先级越高;
2、ext-config中n越大、或越靠后,优先级越高;
3、Shared-dataids < ext-config < 内部;

(2)以新版本来说:

1、shared-configs中n越大、或越靠后,优先级越高;
2、extension-configs中n越大、或越靠后,优先级越高;
3、shared-configs < extension-configs < 内部;

1)逻辑图

在这里插入图片描述
相信大家看了这个图,也不需要做过多解释了。

2)代码

(1)controller:

import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author zhouxin
 * @RefreshScope 动态加载配置
 **/
@RefreshScope
@RestController
public class NacosServerController {

    @Resource
    private ConfigurableApplicationContext configurableApplicationContext;

    /**
     * 可用于验证本服务配置文件和extension-configs之间的优先级
     */
    @Value("${student.name:null}")
    private String name;

    @Value("${config2.name:null}")
    private String config2Name;

    @Value("${config3.name:null}")
    private String config3Name;

    @Value("${config4.name:null}")
    private String config4Name;

    @Value("${config5.name:null}")
    private String config5Name;

    /**
     * 用于验证shared-configs之间的优先级
     */
    @Value("${config.name:null}")
    private String configName;

    /**
     * extension-configs和shared-configs的优先级
     */
    @Value("${ext.name:null}")
    private String extName;

    /**
     * 用于验证extension-configs之间的优先级
     */
    @Value("${ext.gender:null}")
    private String extGender;

    /**
     * 如果只是通过@Value获得的配置信息,不会随着Nacos的修改操作而获得最新配置信息。那么,实时获取最新配置信息有两种方式:
     * 方式1:添加@RefreshScope注解。
     * 方式2:通过getProperty的方式,获得最新的配置信息。
     *
     * @return
     */
    @GetMapping("/name")
    public String getName() {
        String name1 = configurableApplicationContext.getEnvironment().getProperty("student.name");
        return String.format("name=%s <br> name1=%s", name, name1);
    }

    @GetMapping("/allname")
    public String getAllName() {
        return String.format("config1Name=%s<br> config2Name=%s<br> config3Name=%s<br> config4Name=%s <br> config5Name=%s <br> configName=%s <br> extName=%s <br> extGender=%s", name,
                config2Name, config3Name, config4Name, config5Name, configName, extName, extGender);
    }
}

(2)新版本bootstrap.yml配置:

server:
  port: 9001

spring:
  application:
    name: config1
  cloud:
    nacos:
      config:
        # 此处的nacos用于配置管理
        server-addr: 127.0.0.1:8848
        file-extension: yaml
        namespace: 2c38da96-f654-4105-bbc0-63befaa449f0 # 命名空间ID
        group: DEFAULT_GROUP # 指定要获取配置的组
        shared-configs:
          - data-id: config2.yaml
            refresh: true
          - data-id: config3.yaml
            refresh: true
        extension-configs:
          - data-id: config4.yaml
            group: CONFIG4_GROUP
            refresh: true  # 动态刷新配置
          - data-id: config5.yaml
            group: DEFAULT_GROUP
            refresh: true  # 动态刷新配置

(3)老版本bootstrap.yml配置:

server:
  port: 9001

spring:
  application:
    name: config1 # 配置名
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848 # 配置中心地址——单机
        file-extension: yaml # 后缀名
        namespace: 2c38da96-f654-4105-bbc0-63befaa449f0 # 命名空间ID
        group: DEFAULT_GROUP # 指定要获取配置的组

        # 使用shared-dataids,配置加载多个dataId
        shared-dataids: config2.yaml,config3.yaml
        refreshable-dataids: config2.yaml

        # 使用ext-config[n],配置加载多个dataId
        ext-config:
          - data-id: config4.yaml
            group: CONFIG4_GROUP
            refresh: true  # 动态刷新配置
          - data-id: config5.yaml
            group: DEFAULT_GROUP
            refresh: true  # 动态刷新配置

在这里插入图片描述

5、本地和远程配置优先级

SpringCloud中,nacos是借助SpringCloud的Config来加载属性源的,所以是否覆盖系统属性和配置文件属性的设置也是通过SpringCloud的配置进行触发。

默认情况下nacos属性源配置优先级最高,会覆盖系统属性源和配置属性源(本地文件)

可以通过在远程配置中心(Nacos服务中)中做如下配置,设置本地配置覆盖远程配置:

spring:  
  cloud:
    config:
      # Nacos远程配置是否不覆盖其他属性源(文件、系统),默认为false,即覆盖其他源(文件、系统),当allow-override:为true时才会生效
      override-none: true
      # 是否允许Nacos远程配置被本地文件覆盖,默认为true
      allow-override: true
      # Nacos远程配置是否可以覆盖系统属性源(系统环境变量或系统属性),默认为true,即允许
      override-system-properties: false

在这里插入图片描述

注意:

1、将其放在bootstrap.yml或application.yml配置文件中是无效的。
2、如果allow-override值为false,即使将override-none设置为true,也是无效的。

6、其他

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

更多Nacos-config的内容请参考Nacos的GitHub Wiki:https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config

三、最佳实践

仁者见仁智者见智,仅供参考;

1、能放本地、不放远程;避免滥用远程服务器;
2、尽量规避优先级;
3、定规则,例如所有配置属性都要加上注释;
4、配置管理人员尽量少;

最后,虽然我用的Nacos1.4.1版本,但是不建议大家在生产环境使用这个版本,因为该版本存在一个致命的bug:

客户端与 Nacos Server 如果发生短暂的域名解析问题,会导致心跳永久丢失,进而引发服务全量下线,即使网络恢复,也不会自动恢复心跳。

域名解析失败常见于网络抖动或者 K8s 环境下的 coreDNS 访问超时等场景,并且该问题仅存在于 1.4.1 版本,低于此版本不受此问题的影响,使用 1.4.1 的用户建议升级至 1.4.2 以避免此问题(源自阿里内部博文)。

相关文章
|
6天前
|
负载均衡 Java Nacos
SpringCloud基础2——Nacos配置、Feign、Gateway
nacos配置管理、Feign远程调用、Gateway服务网关
SpringCloud基础2——Nacos配置、Feign、Gateway
|
20天前
|
安全 Nacos 数据安全/隐私保护
升级指南:从Nacos 1.3.0 到 2.3.0,并兼容 Seata 的鉴权配置
本文详细介绍了如何在微服务环境下从 Nacos 1.3.0 升级到 2.3.0,并确保 Seata 各版本的兼容性。作者小米分享了升级过程中的关键步骤,包括备份配置、更新鉴权信息及验证测试等,并解答了常见问题。通过这些步骤,可以帮助读者顺利完成升级并提高系统的安全性与一致性。
68 8
升级指南:从Nacos 1.3.0 到 2.3.0,并兼容 Seata 的鉴权配置
|
1月前
|
运维 Java Nacos
Spring Cloud应用框架:Nacos作为服务注册中心和配置中心
Spring Cloud应用框架:Nacos作为服务注册中心和配置中心
|
1月前
|
缓存 Cloud Native Java
【紧急救援】Nacos配置上线后失效?手把手教你如何轻松搞定命名空间修改难题!
【8月更文挑战第15天】Nacos是关键的云原生服务管理平台,用于动态服务发现与配置管理。但在使用其管理微服务配置时,可能会遇到命名空间内的配置更新后不生效的问题。本文探讨此问题并提供解决方案。首先需确认Nacos服务器运行正常及客户端正确连接。接着检查客户端缓存配置,可通过禁用缓存或缩短缓存间隔来即时更新配置。例如,在Spring Cloud Alibaba Nacos配置中心中启用自动刷新功能,并设置每5秒拉取新配置。同时,对于新增配置项,需重启客户端应用。还需检查Nacos服务器日志排除异常,并考虑升级Nacos版本解决兼容性问题。通过这些步骤,通常可有效解决配置不生效的难题。
34 0
|
2月前
|
Java Nacos 数据库
使用 nacos 搭建注册中心及配置中心
使用 nacos 搭建注册中心及配置中心
68 5
|
2月前
|
NoSQL Java Nacos
SpringCloud集成Seata并使用Nacos做注册中心与配置中心
SpringCloud集成Seata并使用Nacos做注册中心与配置中心
73 3
|
1月前
|
应用服务中间件 Nacos 数据库
Nacos 1.2.1 集群搭建(三) Nginx 配置 集群
Nacos 1.2.1 集群搭建(三) Nginx 配置 集群
46 1
|
1月前
|
SQL 关系型数据库 MySQL
Nacos 1.2.1 集群搭建(二)MySQL、cluster 配置
Nacos 1.2.1 集群搭建(二)MySQL、cluster 配置
41 1
|
1月前
|
安全 Nacos 数据库
【技术安全大揭秘】Nacos暴露公网后被非法访问?!6大安全加固秘籍,手把手教你如何保护数据库免遭恶意篡改,打造坚不可摧的微服务注册与配置中心!从限制公网访问到启用访问控制,全方位解析如何构建安全防护体系,让您从此告别数据安全风险!
【8月更文挑战第15天】Nacos是一款广受好评的微服务注册与配置中心,但其公网暴露可能引发数据库被非法访问甚至篡改的安全隐患。本文剖析此问题并提供解决方案,包括限制公网访问、启用HTTPS、加强数据库安全、配置访问控制及监控等,帮助开发者确保服务安全稳定运行。
79 0
|
1月前
|
安全 Nacos 数据安全/隐私保护
【技术干货】破解Nacos安全隐患:连接用户名与密码明文传输!掌握HTTPS、JWT与OAuth2.0加密秘籍,打造坚不可摧的微服务注册与配置中心!从原理到实践,全方位解析如何构建安全防护体系,让您从此告别数据泄露风险!
【8月更文挑战第15天】Nacos是一款广受好评的微服务注册与配置中心,但其连接用户名和密码的明文传输成为安全隐患。本文探讨加密策略提升安全性。首先介绍明文传输风险,随后对比三种加密方案:HTTPS简化数据保护;JWT令牌减少凭证传输,适配分布式环境;OAuth2.0增强安全,支持多授权模式。每种方案各有千秋,开发者需根据具体需求选择最佳实践,确保服务安全稳定运行。
79 0