Nacos Spring Cloud 分布式环境下的配置管理,动态刷新配置

先来看下Nacos官方文档对此是如何实现的

通过 Nacos Server 和 spring-cloud-starter-alibaba-nacos-config 实现配置的动态变更。

通过 Nacos Server 和 spring-cloud-starter-alibaba-nacos-discovery 实现服务的注册与发现。

前提条件

需要先下载 Nacos 并启动 Nacos server。

启动配置管理服务,在Nacos配置管理页面就可以管理服务与配置了

添加依赖:

<dependency>

    <groupId>com.alibaba.cloud</groupId>

    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>

    <version>${latest.version}</version>

</dependency>

注意:版本 2.1.x.RELEASE 对应的是 Spring Boot 2.1.x 版本。版本 2.0.x.RELEASE 对应的是 Spring Boot 2.0.x 版本,版本 1.5.x.RELEASE 对应的是 Spring Boot 1.5.x 版本版本2022.0.0.0-RC1对应的是Spring Boot 3.0.x

在 bootstrap.properties 中配置 Nacos server 的地址和应用名

spring.cloud.nacos.config.server-addr=127.0.0.1:8848

spring.application.name=example

说明:之所以需要配置 spring.application.name ,是因为它是构成 Nacos 配置管理 dataId字段的一部分。

在 Nacos Spring Cloud 中,dataId 的完整格式如下:

${prefix}-${spring.profiles.active}.${file-extension}

prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。

spring.profiles.active 即为当前环境对应的 profile

注意:当 spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension}

file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。

通过 Spring Cloud 原生注解 @RefreshScope 实现配置自动更新:

@RestController

@RequestMapping("/config")

@RefreshScope

public class ConfigController {

    @Value("${useLocalCache:false}")

    private boolean useLocalCache;

    @RequestMapping("/get")

    public boolean get() {

        return useLocalCache;

    }

}

以上是我从Nacos官方文档摘取下来的对配置管理的描述

下面通过跟踪源码分析Nacos启动初始化时是如何从Nacos配置中心获取配置属性的一个执行流程,特别是对配置文件名称命名与Nacos配置中心DataID的命名匹配过程有比较详细的描述,很多时候遇到修改配置属性后不生效,不能动态刷新的问题时,多半也是跟配置文件名称与DataID不匹配导致的

注:以下涉及源码分析对应的版本是:Nacos Spring Cloud 2022.0.0.0-RC1,Spring Boot 3.0.x

启动初始化,准备上下文

创建启动上下文:DefaultBootstrapContext

创建应用上下文:ConfigurableApplicationContext

创建配置环境:ConfigurableEnvironment

通过SpringApplication(当前的启动应用class com.mall.user.UserProviderApplication)初始化应用上下文ConfigurableApplicationContext

SpringApplicationapplyInitializers方法中ApplicationContextInitializer继续初始化

ApplicationContextInitializer是Spring-Context组中的一个函数式接口,其针对各组件提供了相应的实现,常用的实现如下:

org.springframework.boot.web.servlet.support

.ServletContextApplicationContextInitializer基于SpringBoot的Web应用上文初始化的实现

org.springframework.boot.devtools.restart.RestartScopeInitializer,基于SpringBoot热部署的应用上下文初始化的实现

org.apache.dubbo.spring.boot.context.DubboApplicationContextInitializer,基于Dubbo应用上下文的初始化的实现

org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration基于SpringCloud属性源配置的应用初始化的实现

当前项目是基于SpringCloud框架的,所以采用的是PropertySourceBootstrapConfiguration进行初始化,我们继续往下看

applyInitializers方法中,先通过this.getInitializers().iterator()

得到相应的应用上下文初始化实例,这里对应实例就是PropertySourceBootstrapConfiguration接着循环通过相应的实例进行下一步初始化

进入到PropertySourceBootstrapConfigurationinitialize方法,在该方法中PropertySourceBootstrapConfiguration持有一个属性源定位器propertySourceLocators通过该定位器去获取Nacos配置属性,然后继续往下看,中间进过几个层级的调用后进入到PropertySource<?> locate(Environment env)方法

在该方法中,先通过nacosConfigManager得到configService实例,nacosConfigManager(Nacos配置管理)其实也很简单,里面就几行代码,提供了对configService的创建

configService配置服务则是具体的去远程请求Nacos配置中心获取配置,configService在后续流程会讲到,我们接着当前方法继续看

this.nacosPropertySourceBuilder = new NacosPropertySourceBuilder(configService, timeout);

接着将configService交给NacosPropertySourceBuilder实例,以便后续通过该实例去获取配置并构建配置属性

接下来几行代码就是组织Nacos配置中心对应配置文件的Data ID的名称的前缀,通过this.nacosConfigProperties获取配置文件属性来拼接,nacosConfigProperties是配置文件中对应Nacos的属性实体类,通过Spring自动装载并初始化,实体信息如下:

继续看Data ID前缀拼接规则:

1、优先匹配是否有在bootstrap.yml配置文件中设置Nacos配置的前缀prefix

即:sping.cloud.nacos.config.prefix

  1. 如果没置prefix,则匹配Nacos配置的name

即:sping.cloud.nacos.config.name

  1. 如果以上两者都没设置,则匹配当前应用名称

      即:spring.application.name

继续进入到下一个方法loadApplicationConfiguration

看看该方法中的处理逻辑:

1、先调用loadNacosDataIfPresent方法通过参数dataIdPrefix

nacosGroup两个参数去加载配置属性,dataIdPrefix参数就是前面传过来的dataId前缀,nacosGroup则是Nacos配置中心设置的分组

  1. 调用loadNacosDataIfPresent方法,参数为:dataIdPrefixfileExtension配置文件后缀,nacosGroup
  2. 调用loadNacosDataIfPresent方法dataIdPrefixprofile、fileExtensionnacosGroup其中profile为对应的不同环境:dev、test、prod

接在在后续的操作中调用this.nacosPropertySourceBuilder.build(dataId, group, fileExtension, isRefreshable)方法具体构建配置属性,this.nacosPropertySourceBuilder.build方法中会调用loadNacosData(String dataId, String group, String fileExtension)方法

在该方法中先this.configService.getConfig(dataId, group, this.timeout)方法去远程请求Nacos配置中心获取配置属性,接着调用NacosDataParserHandler.getInstance().parseNacosData(dataId, data, fileExtension)方法对获取到的属性进行解析

再进入到configService.getConfig该方法中继续调用getConfigInner

方法

在该方法中先是通过LocalConfigInfoProcessor.getFailover(this.worker.getAgentName(), dataId, group, tenant)方发去本地磁盘去获取配置属性

继续看getConfigInner方法后面的逻辑,如果getFailover方法没有在本地获取到配置属性,则调用this.worker.getServerConfig(dataId, group, tenant, timeoutMs, false)方法发送请求去Nacos配置中心拉取配置属性,到这里Nacos启动初始化从配置中心拉取配置属性的过程就有一个清晰的流程了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值