📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗
🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍
文章目录
写在前面的话
博主所在公司,采用Nacos
作为注册中心和配置中心,在作为配置中心的过程中,总结了一些常见问题点,提供给各部门研发人员查阅。
此篇文章就介绍一下,Nacos
关于加载顺序和动态刷新的那些事情。
Tips:黄四娘家花满蹊,千朵万朵压枝低,留连戏蝶时时舞,自在娇莺恰恰啼。
配置加载顺序和优先级
【配置文件分类】
1、本地配置文件:
bootstrap.yml / bootstrap.yaml
application.yml / application.yaml
2、Nacos 配置中心的配置文件:
共享配置文件 (shared-configs)
扩展配置文件 (extension-configs)
项目应用名配置文件 (${spring.application.name}.yaml/.properties)
【加载顺序】
- 本地的 bootstrap.yml / bootstrap.yaml:首先加载,用于配置应用的启动环境。
- Nacos 配置中心的配置文件:
先加载 共享配置文件 (shared-configs)
然后是 扩展配置文件 (extension-configs)
最后是 项目应用名配置文件 (${spring.application.name}.yaml / .properties)
- 本地的 application.yml / application.yaml:在 Nacos 配置加载之后。
【优先级】
原则上加载顺序和优先级相反,后面加载的会覆盖前面的配置,但Nacos的优先级默认比本地高。
- Nacos 项目应用名配置文件:具有最高优先级。
- Nacos 扩展配置文件:次之,覆盖共享配置。
- Nacos 共享配置文件:优先级低于扩展配置。
- 本地 application.yml / application.yaml:优先级低于所有从 Nacos 加载的配置。
- 本地 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监听效果】
代码读取配置属性
使用@Value读取
配置属性,使用@Value(“${my.name}”)方式注入成员变量,@Value是实现把配置文件的单个属性的提取。
属性若不存在,启动时候就会报错,如下所示:
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各系列,积极备战!