Naocs 2.1.0配置中心源码
2025-07-20 09:46:43 0 举报
Naocs 2.1.0配置中心源码
作者其他创作
大纲/内容
NacosConfigAutoConfiguration自动配置类注册的
加载- ${spring.application.name}
处理@RefreshScope注解
循环内
List<PropertySource<?>> sourceList = new ArrayList<>();
DefaultPublisher
refreshEnvironment();
拉取远程配置并合并
if (!success)
监听这个事件,就可以解决@RefreshScope注解修饰的bean销毁后定时任务失效的问题
SpringBoot提供的加载配置文件的接口
List<PropertySource<?>> sourceList = new ArrayList<>();for (PropertySource<?> p : source) { if (p instanceof EnumerablePropertySource<?> enumerable) { sourceList.add(new BootstrapPropertySource<>(enumerable)); }}composite.addAll(sourceList);
grpc
super.destroy();
Member member = task.member;
构造方法
NacosPropertySourceRepository.getAll()
EventPublisher publisher = INSTANCE.publisherMap.get(topic);
写入历史表,在nacos控制台可以看到配置的历史版本
while (!queue.isEmpty())
加载- ${spring.application.name}-${profile}.${file-extension}
在Spring-cloud-context包中实现,通过SPI机制加载:SpringApplication初始化的过程中会通过SpringFactoriesLoader加载ApplicationContextInitializer类型的实现类
for (ManagerListenerWrap wrap : listeners)
Nacos控制台发布配置,微服务如何感知到的
Unique constraint conflict
NacosConfigBootstrapConfiguration
cacheData.checkListenerMd5();
for (NacosConfigProperties.Config config : configs)
loadSharedConfiguration(composite);
ExternalStoragePersistServiceImpl
run
这个类会按顺序加载bootstrap.yml和application.yml,所以bootstrap.yml的优先级低些
否
receiveEvent(event);
NacosConfigBootstrapConfiguration自动配置类里
nacosConfigProperties.setEnvironment(env);
refreshContext(context)
dumpConfigInfo(dumpAllProcessor);
PropertySourceBootstrapConfiguration
把加了@RefreshScope注解的bean销毁,下去获取bean的时候重新创建,这样bean里面就是最新的属性了。具体原理可以看配置中心使用那节课的笔记。
SpringBooty应用启动
refreshContentAndCheck(changeKey);
catch
通过grpc,从nacos服务端获取配置发生变更的dataid等信息
this.context.publishEvent(new RefreshScopeRefreshedEvent());
cache.addListener(listener);
prepareEnvironment
handle((RefreshEvent) event);
Class<?> driverImplClass = Class.forName(\"com.alibaba.nacos.client.config.NacosConfigService\");
SpringApplication#run
加载- ${spring.application.name}.${file-extension}
impl
nacosRefreshHistory.addRefreshRecord
dataIdPrefix = env.getProperty(\"spring.application.name\");
font color=\"#e855a4\
content = readFileContent(file);
加载bootstrap.yml
循环cacheData里面所有保存的监听器
createConfigService(nacosConfigProperties);
while (lastMaxId < currentMaxId)
NotifyCenter.publishEvent(event);
RefreshEventListener#onApplicationEvent
processTasks();
applyInitializers(context);
CacheData:客户端承载配置的对象,维护了配置项和其下注册的所有监听器
loadNacosDataIfPresent
应用中使用配置中心,指定配置中心以及配置文件都是在bootstrap.yml里配的,application.yml一般不会再去配置,配了也是优先级最低了,因为最新加载
font color=\"#ed77b6\
MD5不一致
ConfigFileApplicationListener.Loader#load
long currentMaxId = persistService.findConfigMaxId();
AbstractSharedListener
if (event instanceof ConfigDataChangeEvent)
agent.start();
发布事件,告诉微服务配置发生变更
return composite;
NacosConfigProperties
composite.addFirstPropertySource(nacosPropertySource);
CacheData cache = cacheMap.get().get(groupKey);
配置越后面加载,优先级越高
return readFile(localPath);
通知所有的订阅者
notifyListenConfig();
ApplicationContextInitializer:Spring的扩展点之一,在ConfigurableApplicationContext#refresh()之前调用,通常用于需要对应用上下文做初始化的web应用中,比如根据上下文环境注册属性源或激活配置文件等
NacosConfigService构造方法
for (ConfigInfoWrapper cf : page.getPageItems())
触发ConfigDataChangeEvent事件,这是客户端能感知到配置更新的根本原因
Collection<PropertySource<?>> source = locator.locateCollection(environment);
@ConfigurationProperties(NacosConfigProperties.PREFIX)public class NacosConfigProperties {/** * Prefix of {@link NacosConfigProperties}. */public static final String PREFIX = \"spring.cloud.nacos.config\";
return ConfigFactory.createConfigService(properties);
分页查询
发布ApplicationReadyEvent事件
final Event event = queue.take();
ConfigController#publishConfig
RpcConfigChangeNotifier#onEvent
NacosPropertySourceRepository.collectNacosPropertySource(nacosPropertySource);
if (request instanceof ConfigChangeNotifyRequest)
配置中心对应配置发生变更,会调用监听器
NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey));
拿到事件发布者
持久化配置信息到数据库
applicationContext.publishEvent
loadExtConfiguration(composite);
异步线程
if (memberManager.getSelf().equals(member))
ConfigRpcTransportClient#initRpcClientHandler
@ComponentExternalDumpService#init
listener.receiveConfigInfo(contentTmp);
ConfigExecutor.executeAsyncNotify(new AsyncRpcTask(rpcQueue));
boolean success = this.queue.offer(event);
微服务引入的Nacos包(Nacos客户端)
NacosConfigManager
for (ApplicationContextInitializer initializer : getInitializers())
this.md5 = getMd5String();
AsyncRpcTask#run
MutablePropertySources propertySources = environment.getPropertySources();
this.registerNacosListenersForApplications()
合并到environment对象里
每个NacosPropertySource对象代表着配置中心的一个配置文件,循环给每个配置文件添加监听器
connection.asyncRequest(request)
service = NacosFactory.createConfigService(nacosConfigProperties.assembleConfigServiceProperties());
initializer.initialize(context);
NotifyCenter.registerSubscriber(new Subscriber() {
先从本地配置拿,拿不到再通过grpc去nacos服务端拿
DumpProcessor
NacosConfigProperties.Config里的属性与我们shared-configs的配置一一对应
for (PropertySourceLocator locator : this.propertySourceLocators)
NacosContextRefresher#onApplicationEvent
YamlPropertySourceLoader#load
response.setContent(content);
this.refresh.refresh();
public static class ConfigContext { String group; String dataId; String tenant;
调用监听器
NotifySingleRpcTask task = queue.poll()
自动配置类,在spring-cloud-starter-alibaba-nacos-config启动包里
调用监听器实现的方法
processor.process(task)
push(rpcPushRetryTask);
PropertySource<?> propertySource = locator.locate(environment);
NacosPropertySourceLocator#locate
此时env对象里已经放入了bootstrap.yml和application.yml的配置
配置数据写入本地磁盘
CacheData cacheData = cacheMap.get().get(groupKey);
如果不是本机,就通知对应节点配置发生变更了
1点几版本用的是http队列,2.1.0版本用的是grpc
EventPublishingRunListener#running
异步
if (!md5.equals(wrap.lastCallMd5))
ClientWorker worker;
Nacos服务端
return DumpConfigHandler.configDump(build.build());
SELECT max(id) FROM config_info
不一致,说明配置发生变更
executeConfigListen();
Listener listener = font color=\"#ed77b6\
while (!executor.isShutdown() && !executor.isTerminated())
jt.update(\
subscriber.onEvent(event);
for (NacosPropertySource propertySource : NacosPropertySourceRepository.getAll())
是
for (ConfigChangeBatchListenResponse.ConfigContext changeConfig : configChangeBatchListenResponse.getChangedConfigs())
根据配置内容,生成MD5,比较前后MD5是否一致,来判断配置是否变更
return publisher.publish(event);
for (Member member : ipList)
数据从本地文件来,而非取数据库里的值,因此你改数据库。配置不会生效
如果md5不一致,说明配置发生了变化
List<NacosConfigProperties.Config> sharedConfigs = nacosConfigProperties.getSharedConfigs();
本地保存一份配置,防止配置中心不可用
队列放不进去了,当前线程执行
ConfigQueryRequestHandler#handle
Collection<Member> ipList = memberManager.allMembers();
获取Nacos集群中所有的节点
把最新的配置更新到Environment对象中
PropertySourceLoader
return nacosPropertySource;
listenExecutebell.offer(bellItem)
final String sql = \
逻辑与shared一致
ProcessRunnable#run
listeners.running(context)
return font color=\"#ed77b6\
startInternal();
String dataId = propertySource.getDataId();
NacosRefreshHistory在NacosConfigAutoConfiguration自动配置类注册的
NacosConfigProperties nacosConfigProperties;
List<PropertySource<?>> composite = new ArrayList<>();
@ServiceAsyncNotifyService
for (Subscriber subscriber : subscribers)
dumpAllProcessor.process(new DumpAllTask());
具体逻辑图灵的源码图有简单画了下,也看不懂
this.scope.refreshAll();
if (cache.md5 == null || !cache.md5.equals(md5))
配置中心属性配置类,对应bootstrap.yml中的配置信息

收藏

收藏
0 条评论
下一页