nacos 配置_Nacos之配置中心

本文深入解析Nacos配置中心的工作原理,从数据源配置开始,详细阐述了配置发布、获取过程,包括长连接、事件监听、配置更新推送等关键环节,揭示了Nacos内部的实现细节。
摘要由CSDN通过智能技术生成

1、阅读源码前的准备

配置数据源

将distribution工程下conf文件夹中的nacos-mysql.sql脚本执行,然后在console工程的application.properties中加入以下数据库的配置:

spring.datasource.platform=mysqldb.num=1### Connect URL of DB:db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTCdb.user=rootdb.password=123456

2、阅读源码

2.1   启动类com.alibaba.nacos.Nacos

添加启动参数:-Dnacos.standalone=true -Dnacos.home=D:\nacos,启动工程即可。

问题:

①:客户端怎么和服务端保持长连接

②:配置更新之后如何进行推送更新

当我们通过控制台添加一个配置并发布的时候,代码实际上执行的是:com.alibaba.nacos.config.server.controller.ConfigController#publishConfig

这里面主要做了两件事:

  • 保存配置信息到数据库

persistService.insertOrUpdate(srcIp, srcUser, configInfo, time, configAdvanceInfo, true);

这个persistService在nacos中有两个实现,分别是:

3d47e3aa931444f787ca83abe409f00d.png

这两个实现本身作为一个Component被加载,而被加载的条件就是使用@Conditional(value = ConditionOnExternalStorage.class)来进行判断: 

public class ConditionOnExternalStorage implements Condition {
            @Override    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            return !PropertyUtil.isEmbeddedStorage();    }    }
  • 发布一个配置变更事件

ConfigChangePublisher        .notifyConfigChange(new ConfigDataChangeEvent(false, dataId, group, tenant, time.getTime()));

既然在这里发布事件,那么就肯定有一个地方在监听这个事件,经过查找我们看到了AsyncNotifyService。

com.alibaba.nacos.config.server.service.ConfigChangePublisher#notifyConfigChange

public static void notifyConfigChange(ConfigDataChangeEvent event) {
        if (PropertyUtil.isEmbeddedStorage() && !ApplicationUtils.getStandaloneMode()) {
            return;    }    NotifyCenter.publishEvent(event);}

com.alibaba.nacos.common.notify.NotifyCenter#publishEvent(Event)

public static boolean publishEvent(final Event event) {
        try {
            return publishEvent(event.getClass(), event);    } catch (Throwable ex) {
            LOGGER.error("There was an exception to the message publishing : {}", ex);        return false;    }}
private static boolean publishEvent(final Class extends Event> eventType, final Event event) {
        final String topic = ClassUtils.getCanonicalName(eventType);    if (ClassUtils.isAssignableFrom(SlowEvent.class, eventType)) {
            return INSTANCE.sharePublisher.publish(event);    }        if (INSTANCE.publisherMap.containsKey(topic)) {
            EventPublisher publisher = INSTANCE.publisherMap.get(topic);        return publisher.publish(event);    }        LOGGER.warn("There are no [{}] publishers for this event, please register", topic);    return false;}

上面这段代码就是从一个事件--->事件发布器中根据事件名称取出发布器,然后执行事件发布,那么接下来,就有几个问题了:

  • publisherMap是在什么时候填充的呢?
    通过搜索代码,我们可以看到这个publisherMap的填充是在com.alibaba.nacos.common.notify.NotifyCenter#registerToPublisher中完成的

  • registerToPublisher什么时候被调用?

09754d2fa0082d5993e56aeb74404535.png

通过观察方法的调用链,我们发现最终是在ServerMemberManager中的构造器里面的init()方法调用到了NotifyCenter#registerToPublisher方法,

2ad7cda772e59545060c97d05eb85a72.png

最终经过这个方法之后,publisherMap里面就主要有三个元素:

f870fd3e1b13b4d89ce3b5b4548cad28.png

到此解决了上面的两个问题,后续将重点说一下这个ServerMemberManager类。

2.2  发布配置
2.2.1 方法调用链

NacosConfigService#publishConfig

        NacosConfigService#publishConfigInner

                 ConfigController#publishConfig

                           ConfigChangePublisher#notifyConfigChange

                                   NotifyCenter#publishEvent(Event)

主要是调用/v1/cs/configs的post请求来发布配置,而该端点对应的controller为ConfigController,方法为publishConfig

主要在com.alibaba.nacos.common.notify.EventPublisher#publish中完成,最终由DefaultPublisher#publish方法完成:


 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值