五 Nacos配置中心源码解析--客户端启动时拉取配置

一 配置中心基本原理

在这里插入图片描述

  • nacosServer将项目持久化到本地数据库中,nacosClient在启动项目的时候从配置中心拉取到相应的配置
  • 客户端通过长轮询机制来实现配置更新时配置的实时刷新(比对文件md5值判断文件是否更新)

二 nacos客户端从配置中心拉取配置的基本流程

在spring cloud中Environment的扩展配置还可以借助PropertySourceBootstrapConfiguration这个ApplicationContextInitializer,通过自定义类实现PropertySourceLocator接口来扩展

org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration#initialize 在刷新容器前触发Environment环境的初始化

@Override
	public void initialize(ConfigurableApplicationContext applicationContext) {
		List<PropertySource<?>> composite = new ArrayList<>();
		AnnotationAwareOrderComparator.sort(this.propertySourceLocators);
		boolean empty = true;
		// 或得environment 对象
		ConfigurableEnvironment environment = applicationContext.getEnvironment();
		for (PropertySourceLocator locator : this.propertySourceLocators) {
			// 通过PropertySourceLocator获得PropertySource
			Collection<PropertySource<?>> source = locator.locateCollection(environment);
			if (source == null || source.size() == 0) {
				continue;
			}
			List<PropertySource<?>> sourceList = new ArrayList<>();
			for (PropertySource<?> p : source) {
				if (p instanceof EnumerablePropertySource) {
					EnumerablePropertySource<?> enumerable = (EnumerablePropertySource<?>) p;
					sourceList.add(new BootstrapPropertySource<>(enumerable));
				}
				else {
					sourceList.add(new SimpleBootstrapPropertySource(p));
				}
			}
			logger.info("Located property source: " + sourceList);
			composite.addAll(sourceList);
			empty = false;
		}
		if (!empty) {
			MutablePropertySources propertySources = environment.getPropertySources();
			String logConfig = environment.resolvePlaceholders("${logging.config:}");
			LogFile logFile = LogFile.get(environment);
			for (PropertySource<?> p : environment.getPropertySources()) {
				if (p.getName().startsWith(BOOTSTRAP_PROPERTY_SOURCE_NAME)) {
					propertySources.remove(p.getName());
				}
			}
			// 将PropertySource初始化到Environment 
			insertPropertySources(propertySources, composite);
			reinitializeLoggingSystem(environment, logConfig, logFile);
			setLogLevels(applicationContext, environment);
			handleIncludedProfiles(environment);
		}
	}

在这里插入图片描述

通过com.alibaba.cloud.nacos.client.NacosPropertySourceLocator#locate完成PropertySource的初始化

@Override
	public PropertySource<?> locate(Environment env) {
		nacosConfigProperties.setEnvironment(env);
		// 获得configService 用于远程接口的调用
		ConfigService configService = nacosConfigManager.getConfigService();

		if (null == configService) {
			log.warn("no instance of config service found, can't load config from nacos");
			return null;
		}
		long timeout = nacosConfigProperties.getTimeout();
		// 用于nacos配置的加载
		nacosPropertySourceBuilder = new NacosPropertySourceBuilder(configService,
				timeout);
		
		// 获得yml中相关配置 用于从服务端获取配置
		String name = nacosConfigProperties.getName();

		String dataIdPrefix = nacosConfigProperties.getPrefix();
		if (StringUtils.isEmpty(dataIdPrefix)) {
			dataIdPrefix = name;
		}

		if (StringUtils.isEmpty(dataIdPrefix)) {
			dataIdPrefix = env.getProperty("spring.application.name");
		}

		CompositePropertySource composite = new CompositePropertySource(
				NACOS_PROPERTY_SOURCE_NAME);
		// 获得公用配置
		loadSharedConfiguration(composite);
		// 获得扩展配置
		loadExtConfiguration(composite);
		// 获得默认配置
		loadApplicationConfiguration(composite, dataIdPrefix, nacosConfigProperties, env);
		return composite;
	}

com.alibaba.cloud.nacos.client.NacosPropertySourceLocator#loadNacosPropertySource中通过nacosPropertySourceBuilder的build或得NacosPropertySource

private NacosPropertySource loadNacosPropertySource(final String dataId,
			final String group, String fileExtension, boolean isRefreshable) {
		if (NacosContextRefresher.getRefreshCount() != 0) {
			if (!isRefreshable) {
				return NacosPropertySourceRepository.getNacosPropertySource(dataId,
						group);
			}
		}
		return nacosPropertySourceBuilder.build(dataId, group, fileExtension,
				isRefreshable);
	}

com.alibaba.cloud.nacos.client.NacosPropertySourceBuilder#build中通過loadNacosData()中的configService远程拉取配置
在这里插入图片描述
com.alibaba.nacos.client.config.NacosConfigService#getConfigInner
在这里插入图片描述

三 总结

在这里插入图片描述

  • PropertySourceBootstrapConfiguration中实现了ApplicationContextInitializer在容器刷新前调用initialize方法在该方法中通过PropertySourceLocator接口的实现locate()方法获得用于environment的装载
  • 在NacosPropertySourceLocator回会依次调用loadSharedConfiguration加载公用配置loadExtConfiguration加载扩展配置loadApplicationConfiguration加载默认配置
  • 配置的加载主要依靠NacosPropertySourceBuilder的build方法他会通过nacosConfigService去向nacos服务端拉取配置
  • nacos服务端在获取配置时会先从本地读取配置读取到相应的配置后直接返回,没有再从数据库读取相应的配置返回给客户端
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值