Nacos 架构原理:一条注册请求会经历什么?下

简介: Nacos 架构原理:一条注册请求会经历什么?下

3 随机节点:平等的世界

我们来看下客户端是如何随机选择一个节点的,流程图如下:

那么如何找到这些代码逻辑呢?思路是怎么样的?

我们之前讲过,RpcClient 会发起 request 请求,用的是和 Nacos 建立 currentConnection 连接来发起调用,代码如下:

// 发起调用
response = this.currentConnection.request(request, timeoutMills);

这个 currentConnection 是客户端和 Nacos 集群中的某个节点建立的连接,我们找下它在哪里赋值的。代码如下:

// 拿到 Nacos 节点信息
serverInfo = recommendServer.get() == null ? nextRpcServer() : recommendServer.get();
// 连接 Nacos 节点
        connectToServer = connectToServer(serverInfo);
// 赋值 currentConnection
        this.currentConnection = connectToServer;

而连接的信息是通过参数 serverInfo 传进去的,所以我们再看下 serverInfo 在哪里赋值的。

这个 nextRpcServer() 方法里面会拿到一个随机的 Nacos 地址:

// 一个 int 随机数,范围 [0 ~ Nacos 个数)
currentIndex.set(new Random().nextInt(serverList.size()));
// index 自增 1
        int index = currentIndex.incrementAndGet() % getServerList().size();
// 返回 Nacos 地址
        return getServerList().get(index);

小结:客户端生成一个随机数,然后通过这个随机数从 Nacos 服务列表中拿到一个 Nacos 服务地址返回给客户端,然后客户端通过这个地址和 Nacos 服务建立连接。Nacos 服务列表中的节点都是平等的,随机拿到的任何一个节点都是可以用来发起调用的。

4 路由转发:不是我的菜

4.1 发起和转发请求的流程

为了演示发起注册的流程,我在这里模拟了一个注册请求。

用的是 curl 命令,对 Nacos 节点(127.0.0.1:8848)发起注册请求:

curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.11&port=8080'

请求 URL:/nacos/v1/ns/instance

请求参数:

  • serviceName=nacos.naming.serviceName
  • ip=20.18.7.11
  • port=8080'

之前我们讲到,Nacos 的有多个节点可以分别处理请求,当节点发现这个请求不是属于自己的,就会进行转发。

如下图所示:

服务 A 随机选择一个 Nacos 节点(图中为 Nacos1)发起注册请求,请求参数中包含了实例信息,Nacos 1 根据实例信息 hash + 取模拿到正确的节点,如果不属于自己,则将请求转发给其他节点(图中为 Nacos2)。

那么路由转发的细节是怎么样的?这个就涉及到 Distro 协议了,我们接着往下看。

4.2 路由转发的逻辑

其实 Nacos 节点的路由转发逻辑比较简单,先来看下流程图:

image.png

步骤如下:

  1. Nacos 节点从客户端发起的 request 中拿到客户端的实例信息生成 distroTag,如 IP + port 或 service name;
  2. Nacos 根据 distroTag 生成 hash 值;
  3. 用 hash 值对 Nacos 节点数进行取余,拿到余数,比如 0、1、2、3;
  4. 根据余数从 Nacos 节点列表中拿到指定的节点地址。

我没看懂的点:我这里启动了三个 Nacos 节点,如下图所示的 三个 Running 节点。但是为什么 Nacos 的 ServersList 会多了一个 192.168.10.197:8848 的节点?

image.png

nacos 控制台有四个节点

4.3 路由转发源码分析

入口文件是 DistroFilter.java:

naming/src/main/java/com/alibaba/nacos/naming/web/DistroFilter.java

请求会先到 DistroFilter 类的 doFilter() 方法,拿到正确的节点地址后,将请求转发出去。

获取需要转发节点地址的代码如下:

// 找到 Nacos 集群中的目标节点
final String targetServer = distroMapper.mapSrv(distroTag);
// mapSrv 方法会先 hash,然后再取模,responsibleTag的值类似这样:"20.18.7.11:8080"
        int index = distroHash(responsibleTag) % servers.size();
// distroHash 方法里面会对 客户端的 ip+port 字符串或者服务名字符串 进行 hash
        Math.abs(responsibleTag.hashCode() % Integer.MAX_VALUE);

不论是自己处理注册请求还是转发给其他节点来处理,都会把实例信息存储起来,那么是如何进行存储的?

5 处理请求:快到碗里来

Nacos 目前有两个版本 v1 和 v2。如果是 v1,则是 instanceController 来处理注册请求,否则用 instanceControllerV2。本篇我们只讲解 v1 版本是怎么处理请求的。

先上流程图:

添加实例信息的流程

测试用的发起注册的命令:

curl -X POST 'http://127.0.0.1:8858/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.11&port=8080'

核心代码就是这个:

image.png服务端注册实例的方法

首先有一个 synchronized 锁,然后执行 put 操作将临时的实例信息存放起来,所以重点看下 这个 consistencyService.put() 方法做了什么事情。

先看下源码:

onPut(key, value);
// 开启 1s 的延迟任务,将数据同步给其他 Nacos 节点
        distroProtocol.sync(new DistroKey(key,KeyBuilder.INSTANCE_LIST_KEY_PREFIX),DataOperation.CHANGE,                             DistroConfig.getInstance().getSyncDelayMillis());

这里面做了三件事情:

  • 将实例信息存放到内存缓存 ConcurrentHashMap 里面;
  • 添加一个任务到 BlockingQueue 队列里面,这个任务就是将最新的实例列表通过 UDP 的方式推送给所有客户端(服务实例),这样客户端就拿到了最新的服务实例列表;
  • 开启 1秒 的延迟任务,将数据通过给其他 Nacos 节点。

总结

本文通过发起一条注册请求,讲解了 Nacos 客户端如何随机选择节点、Nacos Server 如何将请求进行路由转发、Nacos Server 如何存储注册实例。

另外本文用到了集群环境,关于如何搭建和 debug 集群环境,感兴趣的可以留言,后续补上这部分的讲解。

一条注册请求的核心流程



相关文章
|
5月前
|
人工智能 安全 Cloud Native
Nacos 3.0 架构升级,AI 时代更安全的 Registry
随着Nacos3.0的发布,定位由“更易于构建云原生应用的动态服务发现、配置管理和服务管理平台”升级至“ 一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台 ”。
|
2月前
|
人工智能 Java API
Nacos 3.1.0 正式发布,支持 A2A 注册中心与 MCP 注册协议增强
3.1.0 发布核心全新功能-Agent 注册中心,助力构建基于 A2A 协议的多 Agent 协作的AI应用,同时 MCP 注册中心适配最新 MCP 官方注册中心协议及升级优化多项核心功能。
664 25
|
4月前
|
机器学习/深度学习 算法 文件存储
神经架构搜索NAS详解:三种核心算法原理与Python实战代码
神经架构搜索(NAS)正被广泛应用于大模型及语言/视觉模型设计,如LangVision-LoRA-NAS、Jet-Nemotron等。本文回顾NAS核心技术,解析其自动化设计原理,探讨强化学习、进化算法与梯度方法的应用与差异,揭示NAS在大模型时代的潜力与挑战。
1110 6
神经架构搜索NAS详解:三种核心算法原理与Python实战代码
|
2月前
|
机器学习/深度学习 自然语言处理 监控
23_Transformer架构详解:从原理到PyTorch实现
Transformer架构自2017年Google发表的论文《Attention Is All You Need》中提出以来,彻底改变了深度学习特别是自然语言处理领域的格局。在短短几年内,Transformer已成为几乎所有现代大型语言模型(LLM)的基础架构,包括BERT、GPT系列、T5等革命性模型。与传统的RNN和LSTM相比,Transformer通过自注意力机制实现了并行化训练,极大提高了模型的训练效率和性能。
|
5月前
|
存储 监控 算法
园区导航系统技术架构实现与原理解构
本文聚焦园区导航场景中室内外定位精度不足、车辆调度路径规划低效、数据孤岛难以支撑决策等技术痛点,从架构设计到技术原理,对该系统从定位到数据中台进行技术拆解。
245 0
园区导航系统技术架构实现与原理解构
|
6月前
|
人工智能 安全 Cloud Native
Nacos 3.0 架构全景解读,AI 时代服务注册中心的演进
Nacos 3.0 正式发布,定位升级为“一个易于构建 AI Agent 应用的动态服务发现、配置管理和 AI 智能体管理平台”。架构上强化了安全性,引入零信任机制,并支持 MCP 服务管理、AI Registry 等新特性,助力 AI 应用高效开发与运行。
|
2月前
|
Cloud Native Serverless API
微服务架构实战指南:从单体应用到云原生的蜕变之路
🌟蒋星熠Jaxonic,代码为舟的星际旅人。深耕微服务架构,擅以DDD拆分服务、构建高可用通信与治理体系。分享从单体到云原生的实战经验,探索技术演进的无限可能。
微服务架构实战指南:从单体应用到云原生的蜕变之路
|
弹性计算 API 持续交付
后端服务架构的微服务化转型
本文旨在探讨后端服务从单体架构向微服务架构转型的过程,分析微服务架构的优势和面临的挑战。文章首先介绍单体架构的局限性,然后详细阐述微服务架构的核心概念及其在现代软件开发中的应用。通过对比两种架构,指出微服务化转型的必要性和实施策略。最后,讨论了微服务架构实施过程中可能遇到的问题及解决方案。

热门文章

最新文章