Nacos 进阶篇---集群:新增服务实例怎么同步给其他集群节点(十)

一、引言

    在上一章节当中,我们讲解了在Nacos 集群下,集群心跳健康检查定时任务是只会有一个实例去执行的。然后还讲解了怎么把结果同步给其他集群实例的。

   本章我们来讲解下Nacos集群下,新增服务实例是怎么同步给其他集群节点的 ?​​​​​​​​​​​​​​

本章重点

  •  在客户端发起实例注册请求后,注册请求成功后,Nacos服务端是怎么同步给其他集群节点的 ?

二、目录 

目录

一、引言

二、目录 

三、新增实例同步集群节点源码架构分析

四、新增实例同步集群节点源码分析

第一层:内存队列 + 异步任务

第二层:内存队列 + 异步任务

同步集群节点核心方法

五、总结


三、新增实例同步集群节点源码架构分析

首先 Nacos 在 1.4.1 这个版本中,这一块源码,Nacos 是利用 双层内存队列 + 异步任务 来实现的~

第一层:第一层是利用了 ConcurrentHashMap 作为任务储存容器,把Nacos 新增的节点信息包装成 DistroDelayTask 类型任务丢入到 ConcurrentHashMap 当中,然后在DistroTaskEngineHioldet 类中会去创建 DistroDelayTaskExecuteEngine 对象,在 DistroDelayTaskExecuteEngine 对象当中会去调用父类的构造方法,开启延时任务,从而去 ConcurrentHashMap 当去取任务,然后放入到第二层队列当中。

第二层:第二层是利用了 BlockingQueue 作为任务储存容器,第二层接受到第一层的 task 任务,会去先包装成 DistroSyncChangeTask 类型任务,然后放入到阻塞队列 BlockingQueue 当中。在 InnerWorker 中, 会从 BlockingQueue 队列当中获取任务,然后调用 DistroSyncChangeTask 当中的 run 方法。

最后在这个 run 方法当中会去发送HTTP 请求,同步给其他集群节点新增实例信息!

四、新增实例同步集群节点源码分析

那我们接着从第二章客户端发送注册请求,接着讲起。在 DistroConsistencyServiceImpl 类中的 put 方法:

@Override
public void put(String key, Record value) throws NacosException {
    // 实例注册请求,封装任务丢入到阻塞队列中
    onPut(key, value);

    // 本章重点:实例注册请求进行集群节点同步
    distroProtocol.sync(new DistroKey(key, KeyBuilder.INSTANCE_LIST_KEY_PREFIX), DataOperation.CHANGE,
            globalConfig.getTaskDispatchPeriod() / 2);
}
第一层:内存队列 + 异步任务

我们之前在第二章只讲了 onPut(key, value); 方法中实例注册请求的代码,没有讲解 实例注册请求成功后,怎么同步给其他集群节点的,那我们本章就开始讲解distroProtocol.sync 这个方法:

这里 memberManager.allMembersWithoutSelf() 当中获取的集群信息,是从cluster.conf 文件当中读取的

这里为什么要 遍历除开自身以外的所有集群节点 ? 是因为本身的节点是不需要数据同步,只需要同步给其他集群节点即可

然后封装两层,调用 distroTaskEngineHolder.getDelayTaskExecuteEngine().addTask() 方法。

public void sync(DistroKey distroKey, DataOperation action, long delay) {
    // 遍历除开自身以外的所有集群节点
    for (Member each : memberManager.allMembersWithoutSelf()) {
        // 包装第一层
        DistroKey distroKeyWithTarget = new DistroKey(distroKey.getResourceKey(), distroKey.getResourceType(),
                each.getAddress());

        // 包装第二层
        DistroDelayTask distroDelayTask = new DistroDelayTask(distroKeyWithTarget, action, delay);

        // 把新增节点信息包装成 task任务
        distroTaskEngineHolder.getDelayTaskExecuteEngine().addTask(distroKeyWithTarget, distroDelayTask);
        if (Loggers.DISTRO.isDebugEnabled()) {
          
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逸航不吃瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值