本文属于b站图灵课堂springcloud笔记系列。讲得好还不要钱,值得推荐。
官方解释:nacos配置中心实时刷新的原理是什么? | Nacos 官网
专家官方解答 :
Nacos配置中心实时刷新的原理基于以下几个核心步骤与机制,这些信息可以从提供的知识内容中提炼出来:
配置存储与监听: Nacos Server作为配置中心,负责存储所有配置信息。当应用启动并配置了Nacos Config客户端后,客户端会连接到Nacos Server并根据配置的
dataId
和group
订阅相应的配置。@NacosPropertySource与@NacosValue注解: 在Spring Boot应用中,通过
@NacosPropertySource
注解可以指定要加载的配置源(dataId),同时通过autoRefreshed = true
参数开启自动刷新功能。而@NacosValue
注解则用于注入配置值到Bean的字段上,并可通过autoRefreshed = true
使该值具备动态更新的能力。长轮询机制: Nacos客户端实现配置实时更新的一个关键技术是长轮询(Long Polling)。客户端定期向Nacos Server发送请求检查配置是否有更新,如果没有更新,服务器会保持连接不响应,直到有新的配置变更或达到超时时间。这种方式能有效减少网络请求次数,提高效率。
配置变更推送: 当配置在Nacos Server端发生变更时,Nacos Server会立即通知所有订阅了该配置的客户端。客户端收到更新通知后,会立刻获取最新的配置并更新到本地环境,进而更新应用中的相关属性值。
动态更新应用状态: 如示例代码所示,一旦配置值如
useLocalCache
发生变化,通过Nacos Value注入的属性值会自动更新,从而影响到应用的行为,比如从数据库读取数据的策略变化等。综上所述,Nacos配置中心实时刷新的核心在于其客户端与服务端的高效通信机制,以及Spring Boot应用通过注解实现的配置自动绑定与刷新能力,确保了配置变更能够快速、准确地被应用感知并应用到实际运行环境中。
这里老师又给额外拓展了一下长连接轮询的优化方案:
Nacos Client端需要去获取服务端变更的配置内容,但前提是需要先进行比较。也就是说将客户端本地缓存的配置信息和服务器端获取的配置信息进行比较。一旦发现本地缓存的配置内容和服务端的配置内容有差异,那么,就表示服务器端的配置有更新。可能因为客户端的配置比较多,而导致对比的时间较长,使得配置的同步效率非常低。优化:
1、减少网络通信的数据量。客户端把需要进行对比的配置按配置项进行分片,每个分片的大小是3000项。
2分阶段进行对比和更新。
这两个优化的核心目的是去减少网络通信中数据包的大小。把一次大数据包的通信拆分成了多个小数据包的通信。
先这样理解吧,我自己去nacos官网没有找到这个优化的介绍。
2 使用过程
Environment代表了应用的运行时环境,.nacos配置变更后,environment对象中能自动同步变更的数据,可通过其String getProperty(String key)
2.1 配置依赖
<!--nacos-discovery 注册中心依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- nacos-config 配置中心依赖 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency>
2.2 . 配置Nacos服务器地址
可以在application.yml 配置或者推荐在nacos 配置,再application.yml导入
spring:cloud:nacos:discovery:server-addr: 127.0.0.1:8848
2.3 创建配置文件
nacos:我就先用之前storage.yml
新增配置:比如abcd.url
application.yml 使用导入
2.4 使用配置
测试demo1:Environment热更新
使用之前demo:
storage 工程StorageController 引入 Environment,新增测试方法:/getUrl
@Autowiredprivate Environment environment;
//@GetMapping("/getUrl")public String getUrl(){logger.info("getUrl");return environment.getProperty("abcd.url");}
修改nacos 后,不重启应用,直接重新调用接口。
demo2:@Value+@RefreshScope热更新
其余不变。