nacos融合spring cloud学习【Spring-Cloud-Alibaba】

准备

源码链接:gitee.com/mirrors/Spr...

使用分支:2022.x

配置使用【服务注册中心与配置中心都有】

  1. 在父工程的pom文件中声明spring-cloud-alibaba的依赖【控制版本】
  2. 在子工程的pom文件中添加具体依赖
  3. 在配置文件中配置nacos信息【这里使用的是yml配置文件。properties需自行转换】
  4. 确保nacos服务正常,启动服务后nacos的服务列表显示服务信息

Spring-Cloud-Alibaba源码解析

  • nacos-discovery模块
    1. 自动装配配置文件
      spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
java 复制代码
com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration//创建NacosDiscoveryProperties、NacosServiceDiscovery
com.alibaba.cloud.nacos.endpoint.NacosDiscoveryEndpointAutoConfiguration
com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration//创建NacosServiceRegistry、NacosRegistration、NacosAutoServiceRegistration
com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration
com.alibaba.cloud.nacos.discovery.NacosDiscoveryHeartBeatConfiguration
com.alibaba.cloud.nacos.discovery.reactive.NacosReactiveDiscoveryClientConfiguration
com.alibaba.cloud.nacos.discovery.configclient.NacosConfigServerAutoConfiguration
com.alibaba.cloud.nacos.loadbalancer.LoadBalancerNacosAutoConfiguration
com.alibaba.cloud.nacos.NacosServiceAutoConfiguration
com.alibaba.cloud.nacos.util.UtilIPv6AutoConfiguration

2、自动注册
核心在于NacosAutoServiceRegistration的父类AbstractAutoServiceRegistration。在父类中实现了ApplicationListener的onApplicationEvent方法。当ApplicationContext初始化或刷新时触发开始注册方法

  1. spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistryAutoConfiguration.java
  2. org\springframework\cloud\spring-cloud-commons\4.0.0\spring-cloud-commons-4.0.0.jar!\org\springframework\cloud\client\serviceregistry\AbstractAutoServiceRegistration.class【这是spring-cloud提供的,不是alibaba的】
java 复制代码
public void onApplicationEvent(WebServerInitializedEvent event) {
    //ApplicationContext初始化或刷新时触发
    ApplicationContext context = event.getApplicationContext();
    if (!(context instanceof ConfigurableWebServerApplicationContext) || !"management".equals(((ConfigurableWebServerApplicationContext)context).getServerNamespace())) {
        this.port.compareAndSet(0, event.getWebServer().getPort());
        this.start();//※启动
    }
}

public void start() {
    if (!this.isEnabled()) {
        if (logger.isDebugEnabled()) {
            logger.debug("Discovery Lifecycle disabled. Not starting");
        }

    } else {
        if (!this.running.get()) {
            this.context.publishEvent(new InstancePreRegisteredEvent(this, this.getRegistration()));
            this.registrationLifecycles.forEach((registrationLifecycle) -> {
                registrationLifecycle.postProcessBeforeStartRegister(this.getRegistration());
            });
            this.register();//※开始注册
            this.registrationLifecycles.forEach((registrationLifecycle) -> {
                registrationLifecycle.postProcessAfterStartRegister(this.getRegistration());
            });
            if (this.shouldRegisterManagement()) {
                this.registrationManagementLifecycles.forEach((registrationManagementLifecycle) -> {
                    registrationManagementLifecycle.postProcessBeforeStartRegisterManagement(this.getManagementRegistration());
                });
                this.registerManagement();
                this.registrationManagementLifecycles.forEach((registrationManagementLifecycle) -> {
                    registrationManagementLifecycle.postProcessAfterStartRegisterManagement(this.getManagementRegistration());
                });
            }

            this.context.publishEvent(new InstanceRegisteredEvent(this, this.getConfiguration()));
            this.running.compareAndSet(false, true);
        }

    }
}
protected void register() {
        //中间子类也做了逻辑处理,通过后才到这里
        this.serviceRegistry.register(this.getRegistration());//※在注册表中注册
    }
  1. spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java
java 复制代码
@Override
public void register(Registration registration) {

   if (StringUtils.isEmpty(registration.getServiceId())) {
      log.warn("No service to register for nacos client...");
      return;
   }

   NamingService namingService = namingService();//获取命名服务
   String serviceId = registration.getServiceId();
   String group = nacosDiscoveryProperties.getGroup();

   Instance instance = getNacosInstanceFromRegistration(registration);//获取实例

   try {
      namingService.registerInstance(serviceId, group, instance);//※注册实例
      log.info("nacos registry, {} {} {}:{} register finished", group, serviceId,
            instance.getIp(), instance.getPort());
   }
   catch (Exception e) {
      if (nacosDiscoveryProperties.isFailFast()) {
         log.error("nacos registry, {} register failed...{},", serviceId,
               registration.toString(), e);
         rethrowRuntimeException(e);
      }
      else {
         log.warn("Failfast is false. {} register failed...{},", serviceId,
               registration.toString(), e);
      }
   }
}

再往后就是nacos内部的机制了。想看的可以看nacos服务管理学习《实例注册与注销》

  • nacos-config模块
  1. 创建nacos的ConfigService

    通过spring自动装配文件触发NacosConfigAutoConfiguration自动装配类

    spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

java 复制代码
com.alibaba.cloud.nacos.NacosConfigAutoConfiguration//nacos配置中心的自动配置
com.alibaba.cloud.nacos.endpoint.NacosConfigEndpointAutoConfiguration

创建NacosConfigManager的Bean并为ConfigService属性赋值

java 复制代码
@Bean
public NacosConfigManager nacosConfigManager(
      NacosConfigProperties nacosConfigProperties) {
   return new NacosConfigManager(nacosConfigProperties);
}
java 复制代码
public NacosConfigManager(NacosConfigProperties nacosConfigProperties) {
   this.nacosConfigProperties = nacosConfigProperties;
   // Compatible with older code in NacosConfigProperties,It will be deleted in the
   // future.
   createConfigService(nacosConfigProperties);
}

/**
 * Compatible with old design,It will be perfected in the future.
 */
static ConfigService createConfigService(
      NacosConfigProperties nacosConfigProperties) {
   if (Objects.isNull(service)) {
      synchronized (NacosConfigManager.class) {
         try {
            if (Objects.isNull(service)) {
               service = NacosFactory.createConfigService(
                     nacosConfigProperties.assembleConfigServiceProperties());//※通过nacos工厂获取配置服务类
            }
         }
         catch (NacosException e) {
            log.error(e.getMessage());
            throw new NacosConnectionFailureException(
                  nacosConfigProperties.getServerAddr(), e.getMessage(), e);
         }
      }
   }
   return service;
}

再往后就是nacos的内部机制了,想看的可以看nacos-config模块学习《配置中心》

  1. 使用ConfigService获取配置

通过spring核心配置文件META-INF/spring.factories触发NacosConfigDataLoader获取配置

java 复制代码
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.alibaba.cloud.nacos.NacosConfigBootstrapConfiguration
org.springframework.boot.diagnostics.FailureAnalyzer=\
com.alibaba.cloud.nacos.diagnostics.analyzer.NacosConnectionFailureAnalyzer,\
com.alibaba.cloud.nacos.configdata.NacosConfigDataMissingEnvironmentPostProcessor.ImportExceptionFailureAnalyzer
org.springframework.boot.env.PropertySourceLoader=\
com.alibaba.cloud.nacos.parser.NacosJsonPropertySourceLoader,\
com.alibaba.cloud.nacos.parser.NacosXmlPropertySourceLoader
org.springframework.boot.SpringApplicationRunListener=\
com.alibaba.cloud.nacos.logging.NacosLoggingAppRunListener
org.springframework.boot.env.EnvironmentPostProcessor=\
com.alibaba.cloud.nacos.configdata.NacosConfigDataMissingEnvironmentPostProcessor

# ConfigData Location Resolvers
org.springframework.boot.context.config.ConfigDataLocationResolver=\
com.alibaba.cloud.nacos.configdata.NacosConfigDataLocationResolver

# ConfigData Loaders
org.springframework.boot.context.config.ConfigDataLoader=\
com.alibaba.cloud.nacos.configdata.NacosConfigDataLoader//nacos配置数据的加载器

spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/configdata/NacosConfigDataLoader.java

java 复制代码
@Override
public ConfigData load(ConfigDataLoaderContext context,
      NacosConfigDataResource resource) {
   return doLoad(context, resource);
}

public ConfigData doLoad(ConfigDataLoaderContext context,
      NacosConfigDataResource resource) {
   try {
      ConfigService configService = getBean(context, NacosConfigManager.class)
            .getConfigService();//获取配置服务类
      NacosConfigProperties properties = getBean(context,
            NacosConfigProperties.class);

      NacosItemConfig config = resource.getConfig();
      // pull config from nacos
      List<PropertySource<?>> propertySources = pullConfig(configService,
            config.getGroup(), config.getDataId(), config.getSuffix(),
            properties.getTimeout());//※获取配置

      NacosPropertySource propertySource = new NacosPropertySource(propertySources,
            config.getGroup(), config.getDataId(), new Date(),
            config.isRefreshEnabled());

      NacosPropertySourceRepository.collectNacosPropertySource(propertySource);

      return new ConfigData(propertySources, getOptions(context, resource));
   }
   catch (Exception e) {
      log.error("Error getting properties from nacos: " + resource, e);
      if (!resource.isOptional()) {
         throw new ConfigDataResourceNotFoundException(resource, e);
      }
   }
   return null;
}

private List<PropertySource<?>> pullConfig(ConfigService configService, String group,
                String dataId, String suffix, long timeout)
                throws NacosException, IOException {
        String config = configService.getConfig(dataId, group, timeout);//※通过nacos获取配置信息
        logLoadInfo(group, dataId, config);
        // fixed issue: https://github.com/alibaba/spring-cloud-alibaba/issues/2906 .
        String configName = group + "@" + dataId;
        return NacosDataParserHandler.getInstance().parseNacosData(configName, config, suffix);//配置处理
}

再往后就是nacos的内部机制了,想看的可以看nacos-config模块学习《配置中心》

相关推荐
孟婆来包棒棒糖~1 分钟前
SpringCloude快速入门
分布式·后端·spring cloud·微服务·wpf
雾林小妖26 分钟前
springboot集成deepseek
java·spring boot·后端
知识浅谈1 小时前
基于Dify构建本地化知识库智能体:从0到1的实践指南
后端
网络安全打工人1 小时前
CentOS7 安装 rust 1.82.0
开发语言·后端·rust
梦兮林夕2 小时前
04 gRPC 元数据(Metadata)深入解析
后端·go·grpc
pe7er2 小时前
RESTful API 的规范性和接口安全性如何取舍
前端·后端
山风呼呼3 小时前
golang--通道和锁
开发语言·后端·golang
Ice__Cai3 小时前
Django + Celery 详细解析:构建高效的异步任务队列
分布式·后端·python·django
阿华的代码王国3 小时前
【Android】卡片式布局 && 滚动容器ScrollView
android·xml·java·前端·后端·卡片布局·滚动容器
云边散步4 小时前
《校园生活平台从 0 到 1 的搭建》第四篇:微信授权登录前端
前端·javascript·后端