Nacos配置

一、Nacos配置中心

1.基础概念

(1).背景
在系统开发过程中,开发者通常会将一些需要变更的参数、变量等从代码中分离出来独立管理,以独立的配置文件的形式存在。目的是让静态的系统工件或者交付物(如 WAR,JAR 包等)更好地和实际的物理运行环境进行适配。

配置管理一般包含在系统部署的过程中,由系统管理员或者运维人员完成。配置变更是调整系统运行时的行为的有效手段。

  • 如果微服务架构中没有使用统一配置中心时,所存在的问题:
    • 配置文件分散在各个项目里,不方便维护
    • 配置内容安全与权限
    • 更新配置后,项目需要重启

故nacos配置中心就是提供了微服务架构方案下的一套配置中心解决方案。

(2)什么是Nacos的配置中心?
Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。

Spring Cloud Alibaba Nacos Config 是 Config Server 和 Client 的替代方案,客户端和服务器上的概念与 Spring Environment 和 PropertySource 有着一致的抽象,在特殊的 bootstrap 阶段,配置被加载到 Spring 环境中。当应用程序从开发到测试再到生产时,您可以管理这些环境之间的配置,并确保应用程序具有迁移时需要运行的所有内容。

2.Config相关配置

(1)Config配置相关概念
Nacos 数据模型 Key 由三元组唯一确定, Namespace默认是空串,公共命名空间(public),分组默认是 DEFAULT_GROUP

在这里插入图片描述

支持配置的动态更新

修改配置之后,无需重启服务。

支持profile粒度的配置

spring-cloud-starter-alibaba-nacos-config 在加载配置的时候,不仅仅加载了以 dataid 为 s p r i n g . a p p l i c a t i o n . n a m e . {spring.application.name}. spring.application.name.{file-extension:properties} 为前缀的基础配置,还加载了dataid为 s p r i n g . a p p l i c a t i o n . n a m e − {spring.application.name}- spring.application.name{profile}.${file-extension:properties} 的基础配置。在日常开发中如果遇到多套环境下的不同配置,可以通过Spring 提供的 ${spring.profiles.active} 这个配置项来配置。

spring.profiles.active=dev

支持自定义 namespace 的配置

用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。

在没有明确指定 ${spring.cloud.nacos.config.namespace} 配置的情况下, 默认使用的是 Nacos 上 Public 这个namespace。如果需要使用自定义的命名空间,可以通过以下配置来实现:

spring.cloud.nacos.config.namespace=71bb9785-231f-4eca-b4dc-6be446e12ff8

支持自定义 Group 的配置

Group是组织配置的维度之一。通过一个有意义的字符串(如 Buy 或 Trade )对配置集进行分组,从而区分 Data ID 相同的配置集。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。

配置分组的常见场景:不同的应用或组件使用了相同的配置类型,如 database_url 配置和 MQ_topic 配置。

在没有明确指定 ${spring.cloud.nacos.config.group} 配置的情况下,默认是DEFAULT_GROUP 。如果需要自定义自己的 Group,可以通过以下配置来实现:

spring.cloud.nacos.config.group=DEVELOP_GROUP
支持自定义扩展的 Data Id 配置

Data ID 是组织划分配置的维度之一。Data ID 通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。Data ID 通常采用类 Java 包(如 com.taobao.tc.refund.log.level)的命名规则保证全局唯一性。此命名规则非强制。

@RefreshScope动态感知修改后的值

@Value注解可以获取到配置中心的值,但是无法动态感知修改后的值,需要利用@RefreshScope注解。

代码案例如下:

@RestController
@RefreshScope
public class TestController {
@Value("${common.age}")
private String age;
 
@GetMapping("/common")
public String hello() {
    return age;
}

查看mysql数据表的配置信息

查看和修改conf/application.properties文件,增加支持mysql数据源配置(目前只支持mysql),添加mysql数据源的url、用户名和密码。

在这里插入图片描述

(2)配置的优先级
Spring Cloud Alibaba Nacos Config 目前提供了三种配置能力从 Nacos 拉取相关的配置。

A: 通过 spring.cloud.nacos.config.shared-configs 支持多个共享 Data Id 的配置
B: 通过 spring.cloud.nacos.config.ext-config[n].data-id 的方式支持多个扩展 Data Id 的配置
C: 通过内部相关规则(应用名、应用名+ Profile )自动生成相关的 Data Id 配置
当三种方式共同使用时,他们的一个优先级关系是:A < B < C

优先级从高到低:

  1. nacos-config-product.yaml 精准配置

  2. nacos-config.yaml 同工程不同环境的通用配置

  3. ext-config: 不同工程 扩展配置

  4. shared-dataids 不同工程通用配置

官方文档: Nacos config · alibaba/spring-cloud-alibaba Wiki · GitHub

加载流程如下:

springboot启动加载相关文件

在这里插入图片描述

configService加载相关的配置中心文件

在这里插入图片描述

3.配置中心架构设计

业务架构图:

在这里插入图片描述

技术架构图:

在这里插入图片描述

配置中心使用demo

public class ConfigServerDemo {
 
    public static void main(String[] args) throws NacosException, InterruptedException {
        String serverAddr = "localhost";
        String dataId = "nacos-config-demo.yaml";
        String group = "DEFAULT_GROUP";
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
        //获取配置服务
        ConfigService configService = NacosFactory.createConfigService(properties);
        //获取配置
        String content = configService.getConfig(dataId, group, 5000);
        System.out.println(content);
        //注册监听器
        configService.addListener(dataId, group, new Listener() {
            @Override
            public void receiveConfigInfo(String configInfo) {
                System.out.println("===recieve:" + configInfo);
            }
 
            @Override
            public Executor getExecutor() {
                return null;
            }
        });
 
        //发布配置
        //boolean isPublishOk = configService.publishConfig(dataId, group, "content");
        //System.out.println(isPublishOk);
        //发送properties格式
        configService.publishConfig(dataId,group,"common.age=30", ConfigType.PROPERTIES.getType());
 
        Thread.sleep(3000);
        content = configService.getConfig(dataId, group, 5000);
        System.out.println(content);
 
//        boolean isRemoveOk = configService.removeConfig(dataId, group);
//        System.out.println(isRemoveOk);
//        Thread.sleep(3000);
 
//        content = configService.getConfig(dataId, group, 5000);
//        System.out.println(content);
//        Thread.sleep(300000);
 
    }
}

二、nacos config client架构设计和源码实现

配置中心核心接口com.alibaba.nacos.api.config.ConfigService

在这里插入图片描述

1.本地启动获取配置流程

在这里插入图片描述

获取配置的主要方法是 NacosConfigService 类的 getConfig 方法,通常情况下该方法直接从本地文件中取得配置的值,如果本地文件不存在或者内容为空,则再通过 HTTP GET 方法从远端拉取配置,并保存到本地快照中。

当通过 HTTP 获取远端配置时,Nacos 提供了两种熔断策略,一是超时时间,二是最大重试次数,默认重试三次。

(1)获取本地配置文件流程
在这里插入图片描述

(2)远程获取服务端配置文件流程

在这里插入图片描述

server端会在服务端内存也生成对应配置信息,且只有在控制台页面发布更新后,才会刷新。

其位置如下:

在这里插入图片描述

2.注册监听器

配置中心客户端会通过对配置项注册监听器达到在配置项变更的时候执行回调的功能。

NacosConfigService#getConfigAndSignListener

ConfigService#addListener
Nacos 可以通过以上方式注册监听器,它们内部的实现均是调用 ClientWorker 类的 addCacheDataIfAbsent。其中 CacheData 是一个维护配置项和其下注册的所有监听器的实例,所有的 CacheData 都保存在 ClientWorker 类中的原子 cacheMap 中,其内部的核心成员有:
在这里插入图片描述

源码实现流程如下:

主要的思路就是启动的时候为每一个dataID注册一个监听配置信息变更的监听器

在这里插入图片描述

3.配置长轮询

ClientWorker 通过其下的两个线程池完成配置长轮询的工作。

一个是单线程的 executor,每隔 10ms 按照每 3000 个配置项为一批次捞取待轮询的 cacheData 实例,将其包装成为一个 LongPollingTask 提交进入第二个线程池 executorService 处理。
在这里插入图片描述

其源码实现流程如下:

(1)客户端初始化长轮训任务

在这里插入图片描述

(2)客户端长轮训执行任务发起长连接请求判断是否有配置变更

在这里插入图片描述

(3)通知客户端监听器回调配置信息变更

在这里插入图片描述

(4)客户端更新自己的配置信息

在这里插入图片描述

4.nacos config server架构设计和源码实现

(1)服务启动从数据库磁盘拉起配置信息

服务端启动时就会依赖 DumpService 的 init 方法,从数据库中 load 配置存储在本地磁盘上,并将一些重要的元信息例如 MD5 值缓存在内存中。

服务端会根据心跳文件中保存的最后一次心跳时间,来判断到底是从数据库 dump 全量配置数据还是部分增量配置数据(如果机器上次心跳间隔是 6h 以内的话)。

全量 dump 当然先清空磁盘缓存,然后根据主键 ID 每次捞取一千条配置刷进磁盘和内存。

增量 dump 就是捞取最近六小时的新增配置(包括更新的和删除的),先按照这批数据刷新一遍内存和文件,再根据内存里所有的数据全量去比对一遍数据库,如果有改变的再同步一次,相比于全量 dump 的话会减少一定的数据库 IO 和磁盘 IO 次数。

代码执行流程如下:

① 服务启动时开启配置信息同步

在这里插入图片描述

② 将数据库中的配置信息同步到服务器内存文件

在这里插入图片描述

(2)配置发布同步更新
发布配置的代码位于 ConfigController#publishConfig中。

集群部署,请求一开始也只会打到一台机器,这台机器将配置插入Mysql中进行持久化。

服务端并不是针对每次配置查询都去访问 MySQL ,而是会依赖 dump 功能在本地文件中将配置缓存起来。因此当单台机器保存完毕配置之后,需要通知其他机器刷新内存和本地磁盘中的文件内容,因此它会发布一个名为 ConfigDataChangeEvent 的事件,这个事件会通过 HTTP 调用通知所有集群节点(包括自身),触发本地文件和内存的刷新。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当配置信息发生变更后,服务端主要做了一下几种操作

① 更新数据库mysql文件

在这里插入图片描述

其详细操作如下

在这里插入图片描述

更新的场景还会去保留历史版本,并可用通过控制台查询版本记录。

在这里插入图片描述

② 通知注册了动态更新的客户端Client去同步更新自己的配置信息

在这里插入图片描述

③ 刷新服务端本地内存配置信息,并通知集群其他节点同步刷新

在这里插入图片描述

(3)处理长轮询

客户端会有一个长轮询任务,拉取服务端的配置变更,服务端处理逻辑在LongPollingService类中,其中有一个 Runnable 任务名为ClientLongPolling,服务端会将受到的轮询请求包装成一个 ClientLongPolling 任务,该任务持有一个 AsyncContext 响应对象,通过定时线程池延后 29.5s 执行。比客户端 30s 的超时时间提前 500ms 返回是为了最大程度上保证客户端不会因为网络延时造成超时。
在这里插入图片描述

① 接受长连接请求

源码位置:com.alibaba.nacos.config.server.controller.ConfigController#listener

在这里插入图片描述

上面会判断是否有配置信息变更,如果发现有则返回对应的dataid.

② 延迟队列执行任务

在这里插入图片描述

                        版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        原文链接:https://blog.csdn.net/sinat_34814635/article/details/127951267
  • 22
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值