首页 > 编程语言 >SpringCloud Alibaba Nacos 配置动态更新源码学习总结

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

时间:2024-07-03 18:21:21浏览次数:1  
标签:请求 SpringCloud 配置 Nacos nacos 源码 监听器 创建 服务端

众所周知,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

标签:请求,SpringCloud,配置,Nacos,nacos,源码,监听器,创建,服务端
From: https://www.cnblogs.com/LiuFqiang/p/18281321

相关文章

  • springboot实验报告管理系统-计算机毕业设计源码10596
    目录1绪论1.1选题背景与意义1.2国内外研究现状1.3论文结构与章节安排2系统分析2.1可行性分析2.2系统流程分析2.2.1系统开发流程2.2.2用户登录流程2.2.3系统操作流程2.2.4添加信息流程2.2.5修改信息流程2.2.6删除信息流程2.3 系统功能分......
  • springboot实验报告管理系统-计算机毕业设计源码10596
    目录1绪论1.1选题背景与意义1.2国内外研究现状1.3论文结构与章节安排2系统分析2.1可行性分析2.2系统流程分析2.2.1系统开发流程2.2.2用户登录流程2.2.3系统操作流程2.2.4添加信息流程2.2.5修改信息流程2.2.6删除信息流程2.3 系统功能分......
  • django西餐厅管理系统-计算机毕业设计源码10873
    摘要在现代餐饮行业中,高效的管理系统对于西餐厅的成功运营至关重要。为了满足西餐厅日益增长的管理需求,设计并实现了一款基于Python的西餐厅管理系统。Python作为一种简洁而易读的编程语言,具有广泛的应用领域,包括Web开发。结合Django这一强大的Web框架,我们可以快速构建......
  • W外链 短网址系统API 源码,网址缩短API接口
    1、提供的接口W外链提供接口如下:2、签名简介使用前请了解如下事项:API 的签名主要是用于获取身份令牌 AccessToken 时所需必要认证参数在请求需要复杂认证接口的时候,系统会验证 AccessToken在请求获取 AccessToken 的接口时候,服务器会对用户请求合法性的 signature 进......
  • 一个能解决95%定时任务问题的项目,这是什么级别的存在...(领私活源码)
     最近在做项目中涉及到了任务创建和任务运行。结合老大意思,想让我做一个单独的执行器服务。这就有些头疼了。整理起来也比较费事儿!打工人,不能轻易说不!于是就上网划水,突然间XXL-JOB就在我眼前闪过!了解下发现挺适合的。就这样故事开始了...XXL-JOB简介XXL-JOB是一个分......
  • 真太卷了...又开源一款开放API管理工具,支持扩展插件(带私活源码)
     关于API管理工具,相信大家已经都有自己用着顺手的。像国外的Postman,国内有Apifox等等。今天给大家分享的是近期在GitHub比较热门的另一款开放API管理工具:Eoapi。1.Eoapi简介概括来说:这是一款API管理工具,支持扩展插件,简单,开源。Eoapi集合了基础的API管理功能和测试......
  • 记录一次使用easypoi时与源码博弈的过程
     最近刚刚接手了保险一线之声平台的开发和维护工作,第一个需要修复的问题是:平台的事件导出成excel功能在经过一次上线之后突然不可用了,于是就开始了几轮痛苦的排查以及与源码博弈的过程。 二、问题描述一线之声在事件查询菜单下支持将结果导出为Excel,程序中使用easypoi+......
  • Java计算机毕业设计任你行汽车租赁管理系统(开题+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着城市化进程的加速和人们出行需求的日益多样化,汽车租赁行业迎来了前所未有的发展机遇。然而,传统的汽车租赁管理方式往往依赖于人工操作,存在效率低......
  • Java计算机毕业设计基于物联网的农产品冷链物流体系研究(开题+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着消费者对新鲜农产品需求的日益增长,农产品冷链物流体系的重要性日益凸显。然而,传统的农产品冷链物流方式在保障产品质量与安全方面存在诸多不足,如......
  • Java计算机毕业设计服装企业营销活动定制系统(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着时尚行业的蓬勃发展,消费者对服装的需求日益多样化与个性化,这对服装企业的营销活动提出了更高的要求。传统的营销模式已难以满足市场快速变化的需......