没有合适的资源?快使用搜索试试~ 我知道了~
首页Nacos动态配置原理分析
Nacos动态配置原理分析
5星 · 超过95%的资源 需积分: 50 18 下载量 116 浏览量
更新于2023-05-05
评论 1
收藏 2.01MB PDF 举报
客户端是通过一个定时任务来检查自己监听的配置项的数据的,一旦服务端的数据发生变化时,客户端 将会获取到最新的数据,并将最新的数据保存在一个 CacheData 对象中,然后会重新计算 CacheData 的 md5 属性的值,此时就会对该 CacheData 所绑定的 Listener 触发 receiveConfigInfo 回调。
资源详情
资源评论
资源推荐
Nacos动态配置原理分析
一、流程分析
1、入口:NacosConfigAutoConfiguration
首先看一下spring-cloud-starter-alibaba-nacos-discovery项目的结构
看spring.factories中内容,优先加载装配的配置
NacosConfigAutoConfiguration 自动装配配置,进行Bean的初始化
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.alibaba.nacos.NacosConfigBootstrapConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.alibaba.nacos.NacosConfigAutoConfiguration,\
org.springframework.cloud.alibaba.nacos.endpoint.NacosConfigEndpointAutoConfigur
ation
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.cloud.alibaba.nacos.diagnostics.analyzer.NacosConnectionFail
ureAnalyzer
2、远程配置的加载:NacosConfigBootstrapConfiguration
首先远程配置的加载,spring boot通过NacosConfigBootstrapConfiguration中
NacosPropertySourceLocator类实现PropertySourceLocator接口作为入口,具体实现override
locate方法
@Configuration
@ConditionalOnProperty(name = "spring.cloud.nacos.config.enabled",
matchIfMissing = true)
public class NacosConfigAutoConfiguration {
@Bean
public NacosConfigProperties nacosConfigProperties(ApplicationContext
context) {
if (context.getParent() != null
&& BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
context.getParent(), NacosConfigProperties.class).length
> 0) {
return
BeanFactoryUtils.beanOfTypeIncludingAncestors(context.getParent(),
NacosConfigProperties.class);
}
NacosConfigProperties nacosConfigProperties = new
NacosConfigProperties();
return nacosConfigProperties;
}
@Bean
public NacosRefreshProperties nacosRefreshProperties() {
return new NacosRefreshProperties();
}
@Bean
public NacosRefreshHistory nacosRefreshHistory() {
return new NacosRefreshHistory();
}
@Bean
public NacosContextRefresher nacosContextRefresher(
NacosConfigProperties nacosConfigProperties,
NacosRefreshProperties nacosRefreshProperties,
NacosRefreshHistory refreshHistory) {
return new NacosContextRefresher(nacosRefreshProperties, refreshHistory,
nacosConfigProperties.configServiceInstance());
}
}
发现都调了nacosPropertySourceBuilder.build(dataId, group, fileExtension, true);
NacosPropertySourceBuilder中build通过configService.getConfig获取到远程配置。
NacosPropertySource build(String dataId, String group, String fileExtension,
boolean isRefreshable) {
Properties p = loadNacosData(dataId, group, fileExtension);
NacosPropertySource nacosPropertySource = new NacosPropertySource(group,
dataId,
propertiesToMap(p), new Date(), isRefreshable);
NacosPropertySourceRepository.collectNacosPropertySources(nacosPropertySource);
return nacosPropertySource;
}
private Properties loadNacosData(String dataId, String group, String
fileExtension) {
String data = null;
try {
data = configService.getConfig(dataId, group, timeout);
if (!StringUtils.isEmpty(data)) {
log.info(String.format("Loading nacos data, dataId: '%s', group:
'%s'",
dataId, group));
if (fileExtension.equalsIgnoreCase("properties")) {
Properties properties = new Properties();
3、@RefreshScope配置热更新实现原理
RefreshScope:自定义Bean的工作区域,spring默认有单例、原型,还支持扩展Bean Scope,
RefreshScope其中一种
RefreshScope作用:可在Bean运行期间动态刷新
properties.load(new StringReader(data));
return properties;
}
else if (fileExtension.equalsIgnoreCase("yaml")
|| fileExtension.equalsIgnoreCase("yml")) {
YamlPropertiesFactoryBean yamlFactory = new
YamlPropertiesFactoryBean();
yamlFactory.setResources(new
ByteArrayResource(data.getBytes()));
return yamlFactory.getObject();
}
}
}
catch (NacosException e) {
log.error("get data from Nacos error,dataId:{}, ", dataId, e);
}
catch (Exception e) {
log.error("parse data from Nacos error,dataId:{},data:{},", dataId,
data, e);
}
return EMPTY_PROPERTIES;
}
private void registerNacosListener(final String group, final String dataId) {
// 默认匿名监听器
Listener listener = listenerMap.computeIfAbsent(dataId, i -> new Listener()
{
@Override
public void receiveConfigInfo(String configInfo) {
refreshCountIncrement();
String md5 = "";
if (!StringUtils.isEmpty(configInfo)) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md5 = new BigInteger(1, md.digest(configInfo.getBytes("UTF-
8")))
.toString(16);
}
catch (NoSuchAlgorithmException | UnsupportedEncodingException
e) {
log.warn("[Nacos] unable to get md5 for dataId: " + dataId,
e);
}
}
refreshHistory.add(dataId, md5);
//发布刷新事件
applicationContext.publishEvent(
new RefreshEvent(this, null, "Refresh Nacos config"));
RefreshEvent事件监听处理:
org.springframework.cloud.endpoint.event.RefreshEventListener.onApplicationEvent
if (log.isDebugEnabled()) {
log.debug("Refresh Nacos config group " + group + ",dataId" +
dataId);
}
}
@Override
public Executor getExecutor() {
return null;
}
});
try {
configService.addListener(dataId, group, listener);
}
catch (NacosException e) {
e.printStackTrace();
}
}
// 刷新事件处理
public void handle(RefreshEvent event) {
if (this.ready.get()) { // don't handle events before app is ready
log.debug("Event received " + event.getEventDesc());
// 刷新具体逻辑
Set<String> keys = this.refresh.refresh();
log.info("Refresh keys changed: " + keys);
}
}
//org.springframework.cloud.context.refresh.ContextRefresher.refresh
public synchronized Set<String> refresh() {
// 刷新配置,相当于NacosPropertySourceLocator需重新从Nacos配置中心拉取数据
Set<String> keys = refreshEnvironment();
//refreshScope 重新刷新
this.scope.refreshAll();
return keys;
}
//this.scope.refreshAll();
//org.springframework.cloud.context.scope.refresh.RefreshScope.refreshAll
public void refreshAll() {
super.destroy();
// 发布RefreshScopeRefreshedEvent事件,spring默认无监听器,若有特殊业务处理可监
听,例如Eureka
this.context.publishEvent(new RefreshScopeRefreshedEvent());
}
//父类destroy: org.springframework.cloud.context.scope.GenericScope.destroy()
//这里就先把cache清空了,返回了BeanLifecycleWrapper集合。然后拿出前面创建的对应的写锁,上锁
后,进行BeanLifecycleWrapper的销毁。
@Override
剩余22页未读,继续阅读
学无止路
- 粉丝: 1466
- 资源: 8
上传资源 快速赚钱
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- RTL8188FU-Linux-v5.7.4.2-36687.20200602.tar(20765).gz
- c++校园超市商品信息管理系统课程设计说明书(含源代码) (2).pdf
- 建筑供配电系统相关课件.pptx
- 企业管理规章制度及管理模式.doc
- vb打开摄像头.doc
- 云计算-可信计算中认证协议改进方案.pdf
- [详细完整版]单片机编程4.ppt
- c语言常用算法.pdf
- c++经典程序代码大全.pdf
- 单片机数字时钟资料.doc
- 11项目管理前沿1.0.pptx
- 基于ssm的“魅力”繁峙宣传网站的设计与实现论文.doc
- 智慧交通综合解决方案.pptx
- 建筑防潮设计-PowerPointPresentati.pptx
- SPC统计过程控制程序.pptx
- SPC统计方法基础知识.pptx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论5