SpringCloud Alibaba Nacos 配置动态更新源码学习总结

news/2024/7/7 18:58:17/文章来源:https://www.cnblogs.com/LiuFqiang/p/18281321

众所周知,nacos两大核心功能,服务注册发现与动态配置
支持服务注册发现的有:Eureka、Consul、Zookeeper、Nacos
支持动态配置的有:Spring Cloud Config、Nacos、Apollo、Consul
像支持分布式的框架,必须得借用第三方服务,比如定时任务调度xxl-job,分布式事务seata,都分为server端与client端,client端即众多微服务,server端需要单独部署,好在nacos server端也是java编写,所以在spring项目运用更广泛
这里nacos有springboot的版本,隶属于nacos-group,有SpringCloud的版本,隶属于alibaba,一般也会接入Cloud版本的

SpringCloud Alibab有很多出名的组件,这里先记录下服务配置的一些东西,服务注册的后续有时间再看
首先,还是这两个文件,一个是新版本的自动配置,另一个是其他的配置

相比于AutoConfiguration、BootstrapConfiguration更优化,因为它会引导项目启动,做项目启动前的一些准备
打开NacosConfigBootstrapConfiguration,首先映入眼帘的是NacosConfigProperties,spring.cloud.nacos.config为前缀的配置文件

接下来就是NacosConfigManager,主要作用是createConfigService方法创建ConfigService

可以看到的是一个很古老的单例模式

nacos的配置文件加载完了,下面就是这个NacosPropertySourceLocator,算是比较重要的了,用于定位和获取远程配置,查看其实现,发现Spring Cloud Config也用的这个,主要用于实现locate方法
在locate方法中可以看到Environment当前已经当前已经加载的propertySources,是一个CopyOnWriteList


下一个加载的就是当前nacos的Property,因为nacos配置存储与服务端,所以在这个阶段肯定会发起请求,得到服务端的详细配置信息
NacosPropertySourceBuilder 这个类里面build方法会执行实际的逻辑,CompositePropertySource而这个是spring core的类,用于将nacos的property组装到现有的property

loadApplicationConfiguration开始调用配置,会分为三次依次执行,例如项目名叫demo,文件后缀叫yaml,根据文件后缀第一次获取demo, 第二次根据文件名后缀获取demo.yaml,第三次根据activeProfile获取,如果有多个则会获取多次,比如dev环境,获取demo-dev.yaml

并且根据顺序优先级越高,后面加载的优先级会高于前面加载的,因为CompositePropertySource组装所有的property的时候addFirstPropertySource是一个LinedHashSet,先删除再插,将当前的排在第一位

NacosPropertySourceBuilder的loadNacosData根据上面的dataId以及group调用configService,configService是locate方法中通过nacosConfigManager通过单模式创建出来的,nacosConfigManager又通过NacosFactory工厂模式创建出来,
ConfigFactory使用代理模式最终创建

可以看到创建的是NacosConfigService。

在构造器中执行了不少逻辑,第一步创建http请求,同时在start里面开启了一个定时任务在项目启动成功之前校验serverUrl,第二部创建ClientWorker,主要创建线程池以及创建刷新配置的定时任务,

同时获取serverConfig真正发起请求的方法放在了ClientWorker里面,tenant是上游传过来的namespace,开启调用/v1/cs/configs接口,值得注意的是这里如果请求失败直接会抛出NacosException,而在后面没有捕获这个异常,所以如果nacos的serverAddress获取哪个地址配置错误,项目直接会起不来的,

在NacosPropertySourceBuilder的loadNacosData方法中,获取到了配置的信息,下一步是通过NacosDataParserHandler转换为Linedhashmap,因为MapPropertySource需要的source就是map结构

nacos控制端有text,json,yaml,html,properties,所以在解析的时候可以看到也有对应的几种解析方式,但是刚才http返回的是一个string类型的,如何判断服务端是哪一种类型的,


没法判断类型的话那就一个一个来吧,但是通常我们springboot会使用yaml格式,nacos正常也会使用yaml格式的,所以使用的责任链模式,依次执行,这里可以看到首次执行的是yaml解析器


实际执行解析的逻辑还是借用spring里面的YamlMapFactoryBean,解析完成就是下面这样子的,下一步需要做的就是将多层的map进行摊平为一层

至此,远程配置文件以及请求到本地,并且解析完了,已经转换为NacosPropertySource了,正常该进行组装了,这里为了后续逻辑,放入了NacosPropertySourceRepository缓存

这里nacos的三个property将会通过CompositePropertySource放入Environment中,

具体的组装逻辑在PropertySourceBootstrapConfiguration里面insertPropertySources
因为Environment的propertySource是CopyOnWriteList,并且放在最前面

到这里配置就加载完成了,开始执行spring 加载逻辑了
再次查看Enviornment发现最前面三个是刚才新建的nacos配置

动态更新配置

紧着这后面后扫描org.springframework.boot.autoconfigure.EnableAutoConfiguration
会发现里面有个NacosContextRefresher


仔细一看,这个类大有来头,实现了ApplicationListener,泛型是ApplicationReadyEvent,
spring实现发布订阅模式的事件监听器主要有两种方式,第一是实现ApplicationListener接口并且重写onApplicationEvent,第二种是注解形式@EventListener
而监听的这个事件ApplicationReadyEvent也是spring生命周期很重要的一个扩展点,标志着完成了大多数的准备工作,准备开始处理业务请求,
这个时候Spring容器初始化完毕,所有的bean已经被实例化、配置和初始化完成;AutoCOnfiguration自动配置也已经完成;所有视线CommandLineRunner和ApplicationRunner接口的run方法也已经被执行;通过@PostConstruct以及实现了InitializingBean的afterPropertiesSet方法也已经执行完成。
并且在容器初始化之前已经请求过一次配置,这个时候只需要想办法刷新本地的配置与服务端一直就可以,正好借用ApplicationReadyEvent事件,所有准备工作做完之后开始初始化nacos的监听器,来监听服务端的更新

可以看到registerNacosListenersForApplications方法为当前应用创建了一个nacos的监听器,而NacosPropertySourceRepository这个也是比较熟悉了,在放入CompositePropertySource之前先放入了NacosPropertySourceRepository里面的缓存当中取出NacosPropertySource,最终还是在ClientWorker中注册监听器

值得注意的是addCacheDataIfAbsent方法,CacheData是存放配置信息内容的地方,CacheData会首先获取本地快照文件的内容,这个快照内容是发送http请求完成之后立马将原文放入快照文件当中

一般本地快照文件里面是有内容的,默认也是开启了远程同步的,所以远程同步完会覆盖掉之前的content,并且md5值是根据content重新计算

nacos中的listeners也是一个CopyOnWriteArrayList,所以可以给每个CacheData添加多个监听器,并且使用ManagerListenerWrap,可以看到这是正儿八经的装饰器模式,lastCallMd5表示最后一次配置文件的md5值

到这里监听器创建完了,并且set到CacheData里面了,并且ClientWorker里面的cachaeMap里面就是当前的三个CacheData

所有监听器都创建完了,那么在哪开始执行的呢?
在创建ClientWorker的时候,开启了一个10ms的定时任务,主要方法为checkConfigInfo,一直检测cacheMap的情况,因为上面看了源码, 一旦cacheMap有值表示已经请求过服务端的配置信息,并且监听器已创建完成

为了防止有的项目配置文件太多,这里3000个cacheDate分为一个任务,并且开始执行长轮询任务,也就是nacos动态配置核心的开始

上面的check failover config暂时不用看,只需要看check server config,一直到checkUpdateConfigStr,真正发起长轮询的请求,请求服务端的/v1/cs/configs/listener接口

其中param为分组的任务,根据特殊符号进行分割,将dataId,group,namespace以及md5值传到服务端,如果有3000个,将会拼接3000次,这里的timeout为30000


紧接着查看nacos服务端的代码,

首先会在controller中将拼接的客户端信息进行解析,然后会立马进行一次执行,随后如果有变化的话会 马上返回,但是当没有变化,会开启异步线程,异步线程当中执行了一个延迟任务,而延迟时间默认为客户端传过来的30000-500,也就是29.5s

这里ClientMd5Map是上面用特殊符号组装的客户端goup,以及当前的md5值这些,而ConfigCacheService.isUptodate会取出当前服务端最新配置的md5值,如果比较是不一致的,表示当前服务端的配置发送了更新,因为有多个配置,所以在返回response的时候又利用特殊符号拼接进行返回,而此时,这个延迟任务也会结束,发送响应

而客户端接受到之后发现结果不为空,也就是最新的配置更新了,会根据刚才返回的grupKey进行请求配置信息


紧接着会调用cacheData的checkListenerMd5,如果md5值不想同,会发送监听事件修改本地的配置

最终发布RefreshEvent事件

在ContextRefresh中会重新进行刷新Environment

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/736966.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实战篇——SQL注入sqli-labs-master靶场实战三

实战篇——SQL注入sqli-labs-master靶场实战(3) sqlmap基础用法 GET型:POST型:请求头注入(以User-Agent注入为例):爆库: python sqlmap.py -r C:\Users\yaogu\Desktop\sqlmap\request\1.txt --threads 10 --dbs爆表: python sqlmap.py -r C:\Users\yaogu\Desktop\sqlmap\r…

xshell终端显示乱码的处理方法

File -> Properties -> 终端, 编码切换为GBK2312 参考:https://www.cnblogs.com/my-first-blog-lgz/p/17337055.html

web前端应用性能指标测量工具有哪些?

接上一篇介绍前端性能指标的内容,本文主要总结下一般使用的性能测量工具。 1、可以借助 Gooogle 开源的 web-vitals 库来测量一些性能指标: import {onCLS, onINP, onLCP, onFCP, onFID, onTTFB} from web-vitals; onCLS(console.log); onINP(console.log); onLCP(console.lo…

web前端应用应该关注哪些性能指标?

作为一个有经验的前端开发工程师来说,关注性能是必不可少的一项日常工作,那么应该重点关注一些什么样的性能指标呢?其实主要还是从用户体验的角度来看,一般我们会从页面加载相关、交互相关方面入手。 原文:前端性能指标,一网打尽FCP:首次内容绘制 LCP:最大内容绘制 TTF…

解决Centos无法yum源的问题

1、安装yum依赖包,出现报错could not resolve host :mirrorlist.centos.org:unknown error 此时 #ping mirrors.aliyun.com 不通 一般是由于dns解析存在问题,cd /etc/resolv.conf 修改nameserver 改为114.114.114.114。重启网卡:systemctl restart network 再次 #ping mir…

数据万象盲水印 - AIGC的“保护伞”

近期AIGC的爆火让人们觉得AI似乎无所不能,打工人们已然将 AI 发展成了工作的一大助手,但同样也伴随着很多AI的受害者。一些专家、画家、学者们发现自己的“作品风格”正在被 AI “抄袭剽窃”。导语 近期AIGC的爆火让人们觉得AI似乎无所不能,打工人们已然将 AI 发展成了工作的…

VMware vSphere Tanzu部署_12_下载使用Tanzu-K8S工具

下载使用Tanzu-K8S工具Tanzu-K8S工具支持windows、linux、macoswindows下载安装tanzu-k8s工具访问命名空间内的链接到CLI工具链接将二进制文件复制到windows内的system32文件夹内linux下载安装tanzu-k8s工具 # 192.168.203.194这个IP地址替换为您环境下看到的IP地址 wget --no-…

流程表单设计器开源优势多 助力实现流程化!

流程表单设计器开源的优势特点在哪里?一起在本文中寻找答案吧。实现流程化办公是很多职场企业的发展目标。应用什么样的软件可以实现这一目的?低代码技术平台、流程表单设计器开源的优势特点多,在推动企业降本增效、流程化办公的过程中作用明显,是理想的软件平台。那么,流…

在Cocoa里玩转Dock图标

原文来自;https://cocoa.venj.me/blog/play-with-dock-icon/ 今天我们来看一看如何在Cocoa程序中自定义Dock图标。Dock图标的自定义主要包括四方面:加徽章(Badge) 换图标 隐藏和显示最小化时的图标徽章 增加自定义Dock菜单本文将对如何进行这四方面的自定义进行简单的介绍,…

VMware vSphere Tanzu部署_10_开启Tanzu功能

1.开启Tanzu功能 1.1. Tanzu开启的必要条件网络需要为vds网络或者nsx网络 esxi集群需要开启DRS和HA功能 需要配置Tanzu存储策略 需要部署有负载均衡(nsx或者haproxy或者nsx avi) 需要配置有Tanzu Kubernetes内容库1.2. 初始化Tanzu启用Tanzu功能选择tanzu网络为VDS网络选择需要…

如何计算弧线弹道的落地位置

1)如何计算弧线弹道的落地位置2)Unity 2021 IL2CPP下使用Protobuf-net序列化报异常3)编译问题,用Mono可以,但用IL2CPP就报错4)Wwise的Bank在安卓上LoadBank之后,播放没有声音这是第393篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子等技术…

内推失败!

简历的重要性相信大家都是清楚的,简历的好坏直接决定了面试机会的多少,以及是否有面试机会。 例如,上周我这把一个 92 院校的同学推荐给朋友表哥了,他表哥是某知名电商公司 Leader 级别的人物,他去这个 PDD 已经 5 年了,是位不折不扣的大佬,但推荐的结果却令人感到失望,…

Springboot+Vue加密通信

前言本文旨在给出Springboot+Vue 框架下的加密通信具体实现,同时为照顾非行业内/初学读者,第一小节浅显的解释下加解密方式,老鸟直接跳过。 1 加解密方式常见的加解密方式大概分成对称加密、非对称加密与信息摘要算法三类。下面仅从使用角度简单介绍下加解密方式: 1.1 对称…

VMware vSphere Tanzu部署_09_配置tanzu内容库

配置Tanzu内容库Tanzu内容库订阅地址为:https://wp-content.vmware.com/v2/latest/lib.json如下为配置步骤在vcenter中配置内容库即可

Centos7下安装Redis

1.安装依赖 redis是由C语言开发,因此安装之前必须要确保服务器已经安装了gcc,可以通过如下命令查看机器是否安装:gcc -v如果没有安装则通过以下命令安装:yum install -y gcc2.下载redis安装包并解压# 下载,我是在root下执行的下载,所以我的下载目录为:/root/redis-6.2.6…

Winform SynchronizationContext多线程更新画面控件

SynchronizationContext在通讯中充当传输者的角色,实现功能就是一个线程和另外一个线程的通讯。需要注意的是,不是每个线程都附加SynchronizationContext这个对象,只有UI线程是一直拥有的。故获取SynchronizationContext也只能在UI线程上进行SynchronizationContext context…

复数与复变函数选题

【参考】《复变函数论》钟玉泉编 《复变函数论学习指导书》钟玉泉编

Kubernetes基于helm安装 harbor

Kubernetes基于helm安装 harbor 之前harbor的安装都是借助docker完成一键安装部署,安装完成之后harbor组件均运行到一台机器上面,本文实践harbor在k8s环境中的部署。 准备工作 根据harbor官方要求:Kubernetes cluster 1.20+ Helm v3.2.0+结合ingress-nginx版本要求,建议K8S…

pdf的表格怎么转换成word?

Adobe设计PDF文件格式的目的是支持跨平台、多媒体集成的信息出版和发布,特别是对网络信息发布的支持。为了实现这一目标,PDF具有许多其他电子文件格式无法比拟的优势。如今,越来越多的电子书籍、产品描述、公司通知、网络数据和电子邮件开始使用PDF格式文件。但是PDF却不能直…