002-Nacos 简单集群模式源码解析

news/2024/7/5 6:52:01

目录

  • 介绍
    • 架构分析
    • 添加实例-同步信息给其他集群服务
    • 添加实例-提交同步任务
    • 添加实例-执行同步任务
    • 实例健康状态监控

介绍

在这里插入图片描述

Nacos 启动默认会使用集群模式,也就是没有带有-m standalone 的时候就是用的简单集群模式
另外我们再分析单机模式注册实例的时候最后一部分是把本次注册同步给集群其他服务

distroProtocol.sync(new DistroKey(key, KeyBuilder.INSTANCE_LIST_KEY_PREFIX), 
					DataOperation.CHANGE,globalConfig.getTaskDispatchPeriod() / 2);

本文章就来分析下简单集群模式的各种设计和源码

架构分析

简单集群模式下,首先还是实例注册
在集群模式下实例可以注册到任意一台Nacos服务上
Nacos服务自己把本次更新同步给同集群的其他服务

添加实例-同步信息给其他集群服务

sync(DistroKey distroKey, DataOperation action, long delay)//获取除自身外其他的服务Member
for (Member each : memberManager.allMembersWithoutSelf()) {
	//每个 Member在启动的时候都会启动一些列的接口 作为集群 Member 之间通信用
    DistroKey distroKeyWithTarget = new DistroKey(distroKey.getResourceKey(), distroKey.getResourceType(), each.getAddress());
    //组装一个任务 任务内容是 送到哪里 啥作用 延时时间
    DistroDelayTask distroDelayTask = new DistroDelayTask(distroKeyWithTarget, action, delay);
    //添加任务 等待执行
    //其实就是把任务加到一个 ConcurrentHashMap<Object, AbstractDelayTask> tasks 中
    distroTaskEngineHolder.getDelayTaskExecuteEngine().addTask(distroKeyWithTarget, distroDelayTask);
}

添加实例-提交同步任务

有 addTask 肯定就有获取任务并执行的地方

distroTaskEngineHolder.getDelayTaskExecuteEngine()//创建一个定时任务 默认延时 100 ms
processingExecutor.scheduleWithFixedDelay(new ProcessRunnable(), processInterval, processInterval, TimeUnit.MILLISECONDS);
ProcessRunnable#run
processTasks():

//keys = keys.addAll(tasks.keySet());
Collection<Object> keys = getAllTaskKeys();
for (Object taskKey : keys) {
	//获取一个任务  DistroDelayTask 
	AbstractDelayTask task = removeTask(taskKey);
	//获取处理方式
	//这个处理方式 在 DistroHttpRegistry Bean 注册的时候会在@PostConstruct 方法中设置
	//taskEngineHolder.registerNacosTaskProcessor(KeyBuilder.INSTANCE_LIST_KEY_PREFIX,
	//  new DistroHttpDelayTaskProcessor(globalConfig, taskEngineHolder));
	//但是这里设置的key是String类型的 之前设置任务的时候添加的是DistroKey 所以没有匹配的
	//就用的默认的NacosTaskProcessor : new DistroDelayTaskProcessor(this, distroComponentHolder);
	NacosTaskProcessor processor = getProcessor(taskKey);
	//这里会根据返回值判断是否不需要重试 重试就是把任务重新添加回去
	processor.process(task);
}
DistroDelayTaskProcessor#process(NacosTask task):

if (DataOperation.CHANGE.equals(distroDelayTask.getAction())) {
	//这里就是把 key 和 DistroSyncChangeTask 建立关系了
	DistroSyncChangeTask syncChangeTask = new DistroSyncChangeTask(distroKey, distroComponentHolder);
	//DistroExecuteTaskExecuteEngine.addTask(distroKey, executeTask);
	//distroKey : DistroKey
	distroTaskEngineHolder.getExecuteWorkersManager().addTask(distroKey, executeTask);
}


DistroExecuteTaskExecuteEngine#addTask(Object tag, AbstractExecuteTask task):
//这里为空的理由和上面的一样
NacosTaskProcessor processor = getProcessor(tag);
if (null != processor) {
     processor.process(task);
     return;
}
TaskExecuteWorker worker = getWorker(tag);
//这里做的也就是把 task 在放在一个 Queue中 TaskExecuteWorker@BlockingQueue<Runnable> queue
worker.process(task);

添加实例-执行同步任务

正如前边说的:有存放就有获取
在 TaskExecuteWorker 构造函数中就有 new InnerWorker(name).start();

Runnable task = queue.take();
task.run();
DistroSyncChangeTask#run

//type = KeyBuilder.INSTANCE_LIST_KEY_PREFIX
String type = getDistroKey().getResourceType();
//new DistroHttpAgent(memberManager) 中获取了 Datum (也就是 Instances)
DistroData distroData = distroComponentHolder.findDataStorage(type).getDistroData(getDistroKey());
distroData.setType(DataOperation.CHANGE);
//syncData 就是调用 http 发送信息了 /ns/distro/datum 这个不是一个openApi
boolean result = distroComponentHolder.findTransportAgent(type).syncData(distroData, getDistroKey().getTargetServer());

实例健康状态监控

我们知道实例注册后是需要监控健康状态的
但是现在是集群了,集群中只需要有一个服务监控就可以了


http://lihuaxi.xjx100.cn/news/1465267.html

相关文章

三、Kafka生产者

目录 3.1 生产者消息发送流程3.1.1 发送原理 3.2 异步发送 API3.3 同步发送数据3.4 生产者分区3.4.1 kafka分区的好处3.4.2 生产者发送消息的分区策略3.4.3 自定义分区器 3.5 生产者如何提高吞吐量3.6 数据可靠性 3.1 生产者消息发送流程 3.1.1 发送原理 3.2 异步发送 API 3…

Python学习笔记第六十六天(Matplotlib 散点图)

Python学习笔记第六十六天 Matplotlib 散点图散点图 scatter()颜色条 Colormap 后记 Matplotlib 散点图 我们可以使用 pyplot 中的 scatter() 方法来绘制散点图。 散点图 scatter() scatter() 方法语法格式如下&#xff1a; matplotlib.pyplot.scatter(x, y, sNone, cNone,…

C++ 加号运算符重载

通过重载运算符&#xff0c;实现用运算符操作自定义的数据类型。 语法&#xff1a;一个正常的成员函数 把函数名改为operator加上一个操作符。 情况一&#xff08;用成员函数重载运算符&#xff09;&#xff1a; #include<iostream> using namespace std; class Perso…

设计模式——依赖倒转原则

文章目录 基本介绍应用实例依赖关系传递的三种方式和应用案例1, 接口传递&#xff0c;应用案例代码2, 构造方法传递&#xff0c;应用案例代码3, setter 方式传递&#xff0c;应用案例代码 依赖倒转原则的注意事项和细节 基本介绍 依赖倒转原则(Dependence Inversion Principle…

stm32单片机/51单片机蜂鸣器不响(proteus模拟)

蜂鸣器不发生原因就1个&#xff1a;电压不够 所以需要提高蜂鸣器2端的电压&#xff1a;可以采用的方法有&#xff1a; 1提高蜂鸣器电阻&#xff0c;这样根据分压原理&#xff0c;可以提升蜂鸣器2段电压 2更改蜂鸣器的工作电压为更小的值&#xff0c;这个可以通过在proteus内…

Gin+微服务实现抖音视频上传到七牛云

文章目录 安装获取凭证Gin处理微服务处理 如果你对Gin和微服务有一定了解&#xff0c;看本文较容易。 安装 执行命令&#xff1a; go get github.com/qiniu/go-sdk/v7获取凭证 Go SDK 的所有的功能&#xff0c;都需要合法的授权。授权凭证的签算需要七牛账号下的一对有效的A…

2023前端面试笔记 —— HTML5(持续收集更新)

系列文章目录 内容链接2023前端面试笔记HTML5 文章目录 系列文章目录前言一、HTML 文件中的 DOCTYPE 是什么作用二、HTML、XML、XHTML 之间有什么区别三、前缀为 data- 开头的元素属性是什么四、谈谈你对 HTML 语义化的理解五、HTML5 对比 HTML4 有哪些不同之处六、meta 标签有…

【C++随笔01】联合体union —— 一种节省空间的类

【C随笔01】联合体union —— 一种节省空间的类 一、联合体&#xff08;union)二、定义三、用法1、定义union、访问union成员2、匿名union3、使用类管理union成员4、管理并销毁string 一、联合体&#xff08;union) 联合体是一种特殊的类。一个union可以有多个数据成员&#x…