nacos-config源码分析

本文深入剖析了Nacos Config的加载配置流程,从入口NacosConfigBootstrapConfiguration开始,详细讲解了如何通过NacosPropertySourceLocator加载配置,包括从服务端获取配置、使用ConfigService的长轮询监听任务。客户端部分探讨了ConfigService、ClientWorker如何实现配置监听更新,服务端则重点分析了ConfigController和ConfigServletInner的长轮询逻辑。
摘要由CSDN通过智能技术生成

依赖:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

一.入口

1.通过spring.factories注入spring,NacosConfigBootstrapConfiguration

在这里插入图片描述

@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "spring.cloud.nacos.config.enabled", matchIfMissing = true)
public class NacosConfigBootstrapConfiguration {
   

   @Bean
   @ConditionalOnMissingBean
   // 读取nacos相关配置
   public NacosConfigProperties nacosConfigProperties() {
   
      return new NacosConfigProperties();
   }

   @Bean
   @ConditionalOnMissingBean
   //实例化NacosConfigManager,创建ConfigService,ConfigService是配置读取更新的核心类
   public NacosConfigManager nacosConfigManager(
         NacosConfigProperties nacosConfigProperties) {
   
      return new NacosConfigManager(nacosConfigProperties);
   }

   @Bean
   //spring初始化时会调用NacosPropertySourceLocator.locate方法,
   //nacos通过此方法加载nacos-server配置
   public NacosPropertySourceLocator nacosPropertySourceLocator(
         NacosConfigManager nacosConfigManager) {
   
      return new NacosPropertySourceLocator(nacosConfigManager);
   }

}

//NacosPropertySourceLocator.locate方法
//此处只研究loadApplicationConfiguration()加载应用配置,其余同理
//loadExtConfiguration()加载共享配置   shared-configs
//loadExtConfiguration()加载扩展配置    extension-configs
@Override
public PropertySource<?> locate(Environment env) {
   
   ........

   loadSharedConfiguration(composite);
   loadExtConfiguration(composite);
   loadApplicationConfiguration(composite, dataIdPrefix, nacosConfigProperties, env);

   return composite;
}

二.加载config配置

1.NacosPropertySourceLocator.loadApplicationConfiguration方法中调用加载配置方法loadNacosDataIfPresent(),

参数isRefreshable代表是否实时刷新


private void loadNacosDataIfPresent(final CompositePropertySource composite,
      final String dataId, final String group, String fileExtension,
      boolean isRefreshable) {
   
  .........
   //获取配置
   NacosPropertySource propertySource = this.loadNacosPropertySource(dataId, group,
         fileExtension, isRefreshable);
 //将配置交给spring的propertySource管理,之后就可以通过Environment类获取具体配置了
   this.addFirstPropertySource(composite, propertySource, false);
}
2.loadNacosPropertySource()方法
private NacosPropertySource loadNacosPropertySource(final String dataId,
      final String group, String fileExtension, boolean isRefreshable) {
   
  //如果不实时刷新,且已经刷新过了,则从本地缓存的Map里取
   if (NacosContextRefresher.getRefreshCount() != 0) {
   
      if (!isRefreshable) {
   
         return NacosPropertySourceRepository.getNacosPropertySource(dataId,
               group);
      }
   }
   //获取配置
   return nacosPropertySourceBuilder.build(dataId, group, fileExtension,
         isRefreshable);
}
3.NacosPropertySourceBuilder.build()
NacosPropertySource build(String dataId, String group, String fileExtension,
      boolean isRefreshable) {
   
  //加载配置
   Map<String, Object> p = loadNacosData(dataId, group, fileExtension);
   NacosPropertySource nacosPropertySource = new NacosPropertySource(group, dataId,
         p, new Date(), isRefreshable);
 //将配置放到缓存Map
   NacosPropertySourceRepository.collectNacosPropertySource(nacosPropertySource);
   return nacosPropertySource;
}
4.NacosPropertySourceBuilder.loadNacosData()调用了ConfigService.getConfig(dataId, group, timeout);

ConfigService实现NacosConfigService

@Override
public String getConfig(String dataId, String group, long timeoutMs) throws NacosException {
   
    return getConfigInner(namespace, dataId, group, timeoutMs);
}
private String getConfigInner(String tenant, String dataId, String group, long timeoutMs) throws NacosException {
   
    group = null2defaultGroup(group);
    ParamUtils.checkKeyParam(dataId, group);
    ConfigResponse cr = new ConfigResponse();

    cr.setDataId(dataId);
    cr.setTenant(tenant);
    cr.setGroup(group);

    // 优先使用本地文件目录下配置
    String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
    if (content != null) {
   
        LOGGER.warn("[{}] [get-config] get failover ok, dataId={}, group={}, tenant={}, config={}", agent.getName(),
            dataId, group, tenant, ContentUtils.truncateContent(content));
        cr.setContent(content);
        configFilterChainManager.doFilter(null, cr);
        content = cr.getContent();
        return content;
    }

    try {
   
        //从server端拉取配置
        String[] ct = worker.getServerConfig(dataId, group, tenant, timeoutMs);
        cr.setContent(ct[0]);

        configFilterChainManager.doFilter(null, cr);
        content = cr.getContent();

        return content;
    } catch (NacosException ioe) {
   
        if (NacosException.NO_RIGHT == ioe.getErrCode()) {
   
            throw ioe;
        }
        LOGGER.warn("[{}] [get-config] get from server error, dataId={}, group={}, tenant={}, msg={}",
            agent.getName(), dataId, group, tenant, ioe.
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值