《后端程序员 · Nacos 配置优先级&动态刷新》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗
🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍

CSDN.gif

写在前面的话

博主所在公司,采用Nacos作为注册中心和配置中心,在作为配置中心的过程中,总结了一些常见问题点,提供给各部门研发人员查阅。
此篇文章就介绍一下,Nacos 关于加载顺序和动态刷新的那些事情。

Tips:黄四娘家花满蹊,千朵万朵压枝低,留连戏蝶时时舞,自在娇莺恰恰啼。


配置加载顺序和优先级

【配置文件分类】
1、本地配置文件:
bootstrap.yml / bootstrap.yaml
application.yml / application.yaml
2、Nacos 配置中心的配置文件:
共享配置文件 (shared-configs)
扩展配置文件 (extension-configs)
项目应用名配置文件 (${spring.application.name}.yaml/.properties)

【加载顺序】

  1. 本地的 bootstrap.yml / bootstrap.yaml:首先加载,用于配置应用的启动环境。
  2. Nacos 配置中心的配置文件:

先加载 共享配置文件 (shared-configs)
然后是 扩展配置文件 (extension-configs)
最后是 项目应用名配置文件 (${spring.application.name}.yaml / .properties)

  1. 本地的 application.yml / application.yaml:在 Nacos 配置加载之后。

【优先级】

原则上加载顺序和优先级相反,后面加载的会覆盖前面的配置,但Nacos的优先级默认比本地高。

  1. Nacos 项目应用名配置文件:具有最高优先级。
  2. Nacos 扩展配置文件:次之,覆盖共享配置。
  3. Nacos 共享配置文件:优先级低于扩展配置。
  4. 本地 application.yml / application.yaml:优先级低于所有从 Nacos 加载的配置。
  5. 本地 bootstrap.yml / bootstrap.yaml:优先级最低。

【本地配置优先】
在 Nacos 中,可以通过特定的配置来设置本地配置优先,这可以在 bootstrap.yml 或 application.yml 文件中设置:

spring:
  cloud:
    config:
      override-none: true

Tips:作为框架制定人员,不建议这样设置,因为存在某些属性是需要框架设定的,防止被研发人员覆盖。若一些需要被本地覆盖的就不需要定义在Nacos里面了,框架内对应属性实体文件设定默认值即可,有需要可以本地直接覆盖。


配置支持动态刷新

【功能描述】
何谓热更新:Nacos中的配置文件修改后,微服务无需重启就能直接生效。
要实现代码可以实时读取Nacos刷新的配置,有两个重要步骤:
1、检查属性所在的 yml 文件,是否来自于Nacos,并且设置了refresh为true;
2、代码中是否正确的引用属性;

【配置检查】

Tips:共享配置或扩展配置要支持的话,需要添加 refresh 为 true,如下所示。
Tips:external-system.yml refresh配置为true 修改nacos上数据变化会通知刷新
Tips:external-system-old.yml refresh配置为false 修改nacos上数据变化不会动态刷新

system:
  external:
    adapterUrl: http://10.30.120.226:18618/services/
spring:
  application:
    name: pres-service
  cloud:
    nacos:
      # 配置中心
      config:
        # 如果refresh-enabled为false下面shared-configs 所有dataId刷新功能也会失效
        # refresh-enabled 控制是否nacos配置刷新,默认为true 开启的刷新能力。
        # refresh 控制具体dataId指定的配置文件是否动态刷新. 必须在refresh-enabled开启下才能生效。
        refresh-enabled: true
        shared-configs:
          - dataId: external-system.yml # refresh配置为true nacos中external-system.yml数据变化会通知刷新
            group: SERVICE_GROUP
            refresh: true
          - dataId: external-system-old.yml # refresh配置为false nacos中external-system-old.yml数据变化不会动态刷新
            group: SERVICE_GROUP
            refresh: false

【实现方式1:使用@Value + @RefreshScope】 - 不推荐
使用@Value注解的类必须配合@RefreshScope,否则只会使用第一读取到的配置。
不推荐理由:
1、引用属性过于分散,团队开发中,一组类型(system.external)属性最好统一在一个类中,方便统一管理使用,如使用 SystemExternalProperties对象集中管理;
2、开发需要在使用的地方都加上@RefreshScope,容易产生疏漏;

@Component
@RefreshScope
public class HelloService {

    @Value("${system.external.adapterUrl:adapterUrl_undefined}")
    private String adapterUrl;

    public void testAdapterUrl() {
        if ("adapterUrl_undefined".equals(adapterUrl)) {
            //配置为空程序校验处理
        }    
        System.out.println(adapterUrl);
    }
}

【实现方式:使用@ConfigurationProperties】** - 推荐**
使用SpringBoot属性注入,只要adapterUrl对应配置所属dataId开启refresh,则代码中的配置属性可以实时获取nacos中的配置。

//系统外部参数配置都西昂 
@Configuration
@ConfigurationProperties(prefix = "system.external")
public class SystemExternalProperties implements Serializable {
    private String adapterUrl;
    // 其他地址省略
  	// setter/getter省略
}    

【如何查询Nacos监听效果】
image.png


代码读取配置属性

使用@Value读取
配置属性,使用@Value(“${my.name}”)方式注入成员变量,@Value是实现把配置文件的单个属性的提取。
属性若不存在,启动时候就会报错,如下所示:
image.png

Tips:自定义增加的配置,非特殊情况,尽量使用冒号(代表默认值),否则若某现场没该配置,会启动失败。
Tips:添加上冒号代表后面是默认值,冒号后面是空的代表空字符串。

为防止这种情况,可以指定默认值,例如:

@Value("${system.defaultReply:不能识别的信息}")
private String defaultReply;

@Value("${sql.maxRow:1000}")
private String maxRow;

//#{SPEL} Spring表达式
@Value("#{11*2}") 

// 字面量
@Value("true") 

使用 @ConfigurationProperties 绑定实体

@Value 仅适合单个属性的情况,如果属性很多建议用绑定实体的方式。
@ConfigurationProperties可以实现把配置文件的某前缀开始的key自动映射为实体的初值。

1、添加相应的配置文件信息

ali:
  oss:
    accessKeyId: LTAI4FhYdxC7YY8RR6shfXjk
    accessKeySecret: LmVvWUJCQzdQpJyX621Xnf43GasQDO
    bucketName: cjwmy1013
    endPoint: oss-cn-beijing.aliyuncs.com
    fileHost: https://cjwmy1013.oss-cn-beijing.aliyuncs.com/

2、新建一个实体,和配置文件对应,如下:

@Component
@ConfigurationProperties(prefix = "ali.oss")
@Data
public class AliOSSProperties {
    private String accessKeyId;
    private String accessKeySecret;
    private String endPoint;
    private String bucketName;
    private String fileHost;
}

3、注入实体使用。

@Autowired
private AliOSSProperties aliOss;

4、引入 configuration-processor 依赖,这样绑定后可以有提示,也可以跳转,如下:

<!-- 配置文件对应 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

补充:@ConfigurationProperties
配置文件和属性不匹配也不会报错,需要校验,可以添加@Validated和@NotNull注解,如下:

@ConfigurationProperties(prefix = "author")
@Validated
@Component
public class AuthorBean {
    @NotNull
    private String name;
}

总结陈词

此篇文章介绍了Nacos 关于加载顺序和动态刷新的那些事情,仅供学习参考。
💗 近期在整理职场入职新人必读的N各系列,积极备战!

CSDN_END.gif

相关推荐

  1. UGUI - 动态赋值刷新不及时问题

    2024-07-17 15:54:03       59 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 15:54:03       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 15:54:03       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 15:54:03       58 阅读
  4. Python语言-面向对象

    2024-07-17 15:54:03       69 阅读

热门阅读

  1. ES6基本语法(一)

    2024-07-17 15:54:03       22 阅读
  2. 100道ajax面试题、练习题

    2024-07-17 15:54:03       21 阅读
  3. Flask与Django框架比较

    2024-07-17 15:54:03       20 阅读
  4. MPNN消息传递神经网络

    2024-07-17 15:54:03       25 阅读
  5. C# —— (左移 右移 异或 与 或 )运算规则

    2024-07-17 15:54:03       20 阅读
  6. 知识加油站

    2024-07-17 15:54:03       20 阅读
  7. 鹈鹕优化算法(POA)及其Python和MATLAB实现

    2024-07-17 15:54:03       22 阅读
  8. 互联网开发工作现状的深度剖析

    2024-07-17 15:54:03       20 阅读