【Nacos架构 原理】内核设计之Nacos寻址机制
文章目录
- 前提
- 设计
- 内部实现
- 单机寻址
- 文件寻址
- 地址服务器寻址
前提
对于集群模式,集群内的每个Nacos成员都需要相互通信。因此这就带来一个问题,该以何种方式去管理集群内部的Nacos成员节点信息,即Nacos内部的寻址机制。
设计
要能够感知到节点的变更情况:节点是增加了还是减少了;当前最新的成员列表信息是什么;以何种方式去管理成员列表信息;如何快速的支持新的、更优秀的成员列表管理模式等等。
针对上述需求点,我们抽象出了一个 MemberLookup 接口,具体设计如下:
public interface MemberLookup {/*** start.** @throws NacosException NacosException*/void start() throws NacosException;/*** Inject the ServerMemberManager property.** @param memberManager {@link ServerMemberManager}*/void injectMemberManager(ServerMemberManager memberManager);/*** The addressing pattern finds cluster nodes.** @param members {@link Collection}*/void afterLookup(Collection<Member> members);/*** Addressing mode closed.** @throws NacosException NacosException*/void destroy() throws NacosException;
}
(ServerMemberManager
存储着本节点所知道的所有成员节点列表信息,提供了针对成员节点的增删改查操作,同时维护了一个 MemberLookup
列表,方便进行动态切换成员节点寻址方式。)
可以看到,MemberLookup
接口非常简单,核心接口就两个—— injectMemberManager
以及 afterLookup
,前者用于将 ServerMemberManager
注入到 MemberLookup
中,方便利用 ServerMemberManager
的存储、查询能力,后者 afterLookup
则是一个事件接口,当 MemberLookup
需要进行成员节点信息更新时,会将当前最新的成员节点列表信息通过该函数进行通知给 ServerMemberManager
,具体的节点管理方式,则是隐藏到具体的 MemberLookup
实现中。
内部实现
单机寻址
com.alibaba.nacos.core.cluster.lookup.StandaloneMemberLookup
单机模式的寻址模式很简单,其实就是找到自己的IP:PORT组合信息,然后格式化为一个节点信息,调用afterLookup
然后将信息存储到 ServerMemberManager
中。
public class StandaloneMemberLookup extends AbstractMemberLookup {@Overridepublic void start() {if (start.compareAndSet(false, true)) {String url = InetUtils.getSelfIp() + ":" + ApplicationUtils.getPort();afterLookup(MemberUtils.readServerConf(Collections.singletonList(url)));}}
}
文件寻址
com.alibaba.nacos.core.cluster.lookup.FileConfigMemberLookup
文件寻址模式是 Nacos 集群模式下的默认寻址实现。文件寻址模式很简单,其实就是每个 Nacos 节点需要维护一个叫做 cluster.conf
的文件,如下;
192.168.16.101:8847
192.168.16.102
192.168.16.103
该文件默认只需要填写每个成员节点的 IP 信息即可,端口会自动选择 Nacos 的默认端口 8848,如果说有特殊需求更改了 Nacos 的端口信息,则需要在该文件将该节点的完整网路地址信息补充完整(IP:PORT)
当 Nacos节点启动时,会读取该文件的内容,然后将文件内的 IP 解析为节点列表,调用 afterLookup
存入ServerMemberManager
。
private void readClusterConfFromDisk() {Collection<Member> tmpMembers = new ArrayList<>();try {List<String> tmp = ApplicationUtils.readClusterConf();tmpMembers = MemberUtils.readServerConf(tmp);} catch (Throwable e) {Loggers.CLUSTER.error("nacos-XXXX [serverlist] failed to get serverlist from disk!, error : {}", e.getMessage());}afterLookup(tmpMembers);
}
如果发现集群扩缩容,那么就需要修改每个 Nacos 节点下的 cluster.conf 文件,然后 Nacos 内部的文件变动监听中心会自动发现文件修改,重新读取文件内容、加载 IP 列表信息、更新新增的节点。
private FileWatcher watcher = new FileWatcher() {@Overridepublic void onChange(FileChangeEvent event) {readClusterConfFromDisk();}@Overridepublic boolean interest(String context) {return StringUtils.contains(context, "cluster.conf");}
};public void start() throws NacosException {if (start.compareAndSet(false, true)) {readClusterConfFromDisk();// Use the inotify mechanism to monitor file changes and automatically// trigger the reading of cluster.conftry {WatchFileCenter.registerWatcher(ApplicationUtils.getConfFilePath(), watcher);} catch (Throwable e) {Loggers.CLUSTER.error("An exception occurred in the launch file monitor : {}", e.getMessage());}}
}
默认寻址模式有一个缺点——运维成本较大,可以想象下,当你新增一个 Nacos 节点时,需要去手动修改每个 Nacos 节点下的 cluster.conf 文件,这是多么辛苦的一件工作,或者稍微高端一点,利用 ansible 等自动化部署的工具去推送 cluster.conf 文件去代替自己的手动操作,虽然说省去了较为繁琐的人工操作步骤,但是仍旧存在一个问题——每一个 Nacos 节点都存在一份 cluster.conf 文件,如果其中一个节点的 cluster.conf 文件修改失败,就造成了集群间成员节点列表数据的不一致性,因此,又引申出了新的寻址模式——地址服务器寻址模式。
地址服务器寻址
com.alibaba.nacos.core.cluster.lookup.AddressServerMemberLookup
地址服务器寻址模式是 Nacos 官方推荐的一种集群成员节点信息管理,该模式利用了一个简易的 web 服务器,用于管理 cluster.conf 文件的内容信息,这样,运维人员只需要管理这一份集群成员节点内容即可,而每个Nacos 成员节点,只需要向这个 web 节点定时请求当前最新的集群成员节点列表信息即可。
因此,通过地址服务器这种模式,大大简化了 Nacos 集群节点管理的成本,同时,地址服务器是一个非常简单的 web 程序,其程序的稳定性能够得到很好的保障。
相关文章:

【Nacos架构 原理】内核设计之Nacos寻址机制
文章目录 前提设计内部实现单机寻址文件寻址地址服务器寻址 前提 对于集群模式,集群内的每个Nacos成员都需要相互通信。因此这就带来一个问题,该以何种方式去管理集群内部的Nacos成员节点信息,即Nacos内部的寻址机制。 设计 要能够感知到节…...

入门案例:mybatis流程,核心,常见错误
入门案例:mybatis执行流程分析 说明: 1.第一步:是从核心配置文件mybatis-config.xml中构建SqlSessionFactory对象,由于核心配置文件mybatis-config.xml中关联了映射文件UserMapper.xml,所以在SqlSessionFactory中也存在映射文件的…...

C++ | Leetcode C++题解之第456题132模式
题目: 题解: class Solution { public:bool find132pattern(vector<int>& nums) {int n nums.size();vector<int> candidate_i {nums[0]};vector<int> candidate_j {nums[0]};for (int k 1; k < n; k) {auto it_i upper_…...

自然语言处理问答系统
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
Python的几个高级特性
引言 Python是一种功能强大的编程语言,它简洁的语法和强大的库支持使其成为数据科学和机器学习领域的热门选择。在Python的高级特性中,生成器、迭代器、闭包、装饰器和内置高阶函数是实现高效、优雅代码的关键。本文将逐一介绍这些特性,并提…...

【颜色平衡树 / E】
题目 思路 DFS暴力 60分 代码 #include <bits/stdc.h> using namespace std; const int N 5010; const int M 5010; int h[N], e[M], ne[M], idx; int c[N], f; int ans; void add(int a, int b) // 添加一条边a->b {e[idx] b, ne[idx] h[a], h[a] idx ; } …...

滑动窗口--(中篇)
将X减到0的最小操作数 给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。 如果可以将 x 恰好 减到 0 ,返…...
Java性能调优:实战技巧与最佳实践
引言 Java作为企业级应用开发的首选语言之一,其性能直接影响到系统的响应速度和用户体验。性能调优是一项复杂的工作,涉及多个层面的知识和技术。本文将通过具体的示例,探讨一些常见的性能调优技巧及最佳实践。 1. 了解你的应用程序 示例&…...

排版套料系统设计说明
先上效果图 项目地址 1.产品介绍 产品名称:StreamFit 智能排版套料系统 主要功能: 智能排版优化 功能描述:StreamFit 利用先进的算法技术,自动对各类材料(如布料、金属板材、纸张等)进行高效排版布局&am…...

算法修炼之路之二分查找
目录 一:三大二分介绍及模板 1.普通二分 2.查找左右边界的二分及模板 二:LeetCode OJ练习 1.第一题 2.第二题 3.第三题 4.第四题 5.第五题 6.第六题 一:三大二分介绍及模板 1.普通二分 这里通过一道题来引出普通二分及模板 LeetCode_704 二分查找 画图分析: 具体代…...

OpenAI预计明年将推出“代理”系统
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...

每日OJ题_牛客_重排字符串_贪心_C++_Java
目录 牛客_重排字符串_贪心 题目解析 C代码 Java代码 牛客_重排字符串_贪心 重排字符串 (nowcoder.com) 描述: 小红拿到了一个只由小写字母组成的字符串。她准备把这个字符串重排(只改变字母的顺序,不改变数量) …...
Python 进阶部分详细整理
1. 面向对象编程(OOP) 面向对象编程 (OOP) 是一种通过将程序中的数据和功能封装为对象的编程范式。OOP 基于四个核心概念:类与对象、继承、封装与多态。 类与对象 类(Class):类是创建对象的蓝图或模板。它…...

[ RK3566-Android11 ] 关于移植 RK628F 驱动以及后HDMI-IN图像延迟/无声等问题
问题描述 由前一篇文章https://blog.csdn.net/jay547063443/article/details/142059700?fromshareblogdetail&sharetypeblogdetail&sharerId142059700&sharereferPC&sharesourcejay547063443&sharefromfrom_link,移植HDMI-IN部分驱动后出现&a…...

【黑马点评】 使用RabbitMQ实现消息队列——2.使用RabbitMQ监听秒杀下单
2 使用RabbitMQ实现消息队列 2.1 修改\hm-dianping\pom.xmlpom.xml文件 添加RabbitMQ的环境 <!-- RabbitMQ--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId> </depe…...

业务封装与映射 -- OTUk/ODUk/OPUk开销帧结构
开销是为了保证净荷正常、灵活传送所必须附加的供网络运行、管理和维护(OAM)使用的字节。 OTN电层开销包括OTUk开销、ODUk开销、OPUk开销、OTUCn开销、ODUCn开销、OPUCn开销和帧对齐开销。 SM开销属于OTU开销,占用3个字节;PM开销…...
Vim基本用法
Vim用法 一、基本模式 1. 普通模式(Normal Mode) 移动光标 基本移动:使用方向键(h左移、j下移、k上移、l右移),也可以使用 H(移到屏幕顶部)、M(移到屏幕中间ÿ…...
python 实现Tarjan 用于在有向图中查找强连通分量的算法
Tarjan 用于在有向图中查找强连通分量的算法介绍 Tarjan算法是一种用于在有向图中查找强连通分量的高效算法,由Robert Tarjan在1972年提出。强连通分量是指在有向图中,如果从顶点u到顶点v以及从顶点v到顶点u都存在一条路径,那么顶点u和顶点v…...
Qt开发技巧(十五)字符串去除空格,跨网段搜索不生效,设置图片显示失败问题,表格视图的批量删除,主动判断字串编码,开启向前查询的属性,画家类载入html来绘制
继续讲一些Qt开发中的技巧操作: 1.字符串去除空格 我们经常会遇到字符串重去除空格的情况,对于QString去除空格,有多种场景,可能需要去除左侧、右侧、所有等位置的空格; //字符串去空格 -1移除左侧空格 0移除所有空格…...

【机器学习】智驭未来:探索机器学习在食品生产中的革新之路
📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀目录 🔍1. 引言:探索机器学习在食品生产中的革新之路📒2. 机器学习在食品质量控制中的应用🌞实…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...

网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...

如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...