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

avatar
作者
猴君
阅读量:2

📢 大家好,我是 【战神刘玉栋】,有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

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!