5000 字 | Nacos 架构原理①:一条注册请求会经历什么?(一)

HoverInTheSky
发布于 2022-6-28 17:49
浏览
0收藏

前言


上篇我们讲解了如何使用 Nacos 作为注册中心和配置中心。

 

6000 字|20 图|Nacos 手摸手教程

 

这次我们来聊下 Nacos 的注册服务的底层原理。

 

Nacos 作为注册中心,用来接收客户端(服务实例)发起的注册请求,并将注册信息存放到注册中心进行管理。

 

那么一条注册请求到底会经历哪些步骤呢?


知识点预告


先上一张整体的流程图:5000 字  | Nacos 架构原理①:一条注册请求会经历什么?(一)-鸿蒙开发者社区 •  集群环境:如果是 Nacos 集群环境,那么拓扑结构是什么样的。
 •  组装请求:客户端组装注册请求,下一步对 Nacos 服务发起远程调用。
 •  随机节点:客户端随机选择集群中的一个 Nacos 节点发起注册,实现负载均衡。
 •  路由转发:Nacos 节点收到注册请求后,看下是不是属于自己的,不是的话,就进行路由转发。
 •  处理请求:转发给指定的节点后,该节点就会将注册请求中的实例信息解析出来,存到自定义的内存结构中。
 •  最终一致性:通过 Nacos 自研的 Distro 协议执行延迟异步任务,将注册信息同步给集群中的其他节点,保证了数据的最终一致性。
 •  异步重试:如果注册失败,客户端将会切换 Nacos 节点,再次发起注册请求,保证高可用性。

 

这些知识点里面还有很多细节,我会通过画图 + 源码剖析的方式给大家解答。如果遇到源码看不太懂的地方,可以多看下我画的图,然后翻下源码,对照着一起看。

 

小 Tip:本文使用的 Nacos 版本:2.0.4。

 

一、源头:发起注册


1.1 阅读源码的小技巧


上篇我们讲到加上一个注解 @EnableDiscoveryClient 就可以使服务自动注册到 Nacos。

 

那么这个发起注册的地方到底在哪呢?注册信息又是长什么样的呢?


告诉大家一个看源码的小技巧,拿到源码后,不是直接各个文件都看一篇,而是先看源码中带的 example 文件夹。如下图所示,找到 example 的 App 类,里面就有发起注册的实例代码。如下图所示:5000 字  | Nacos 架构原理①:一条注册请求会经历什么?(一)-鸿蒙开发者社区当然,我们也可以通过官网给的 curl 命令发起 HTTP 请求:

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

留个问题:我们都是加一个 Nacos 注解 @EnableDiscoveryClient,就会自动把服务实例注册到 Nacos,这个是怎么做到的?

 

1.2 发起注册的流程图


先来看一下代码的流程图:5000 字  | Nacos 架构原理①:一条注册请求会经历什么?(一)-鸿蒙开发者社区跟着这个流程图,我们 debug 来看下。

 

1.3 组装注册的实例信息


入口的核心代码如下图所示,它会组装注册的实例信息,放到一个 instance 变量里面:5000 字  | Nacos 架构原理①:一条注册请求会经历什么?(一)-鸿蒙开发者社区通过代码调试,我们可以看到里面的实例信息长这样:5000 字  | Nacos 架构原理①:一条注册请求会经历什么?(一)-鸿蒙开发者社区1.4 组装注册请求 request


发起注册的核心方法是 doRegisterService(),组装的 request 如下图所示,里面有之前组装的实例信息 instance,还有指定的  namespace(Nacos 的命名空间)、serviceName(服务名),groupName(Nacos 的分组)。

5000 字  | Nacos 架构原理①:一条注册请求会经历什么?(一)-鸿蒙开发者社区

 发起注册的源码


1.5 发起远程调用


requestToServer() 方法里面会调用 RpcClient 的 request() 方法:

response = this.currentConnection.request(request, timeoutMills);

就是向 Nacos 发起远程调用,如果是 Nacos 集群,则是向集群中的某个 Nacos 节点发起远程调用。

 

接下来我们看下客户端是如何选择一个 Nacos 节点进行注册的。

 

二、集群环境:分布式的前提


如果是 Nacos 集群环境,客户端会随机选择一个 Nacos 节点发起注册。

 

2.1 搭建好一套Nacos 集群环境


为了讲解客户端是如何注册到 Nacos 集群环境的底层原理,我在本地搭建了一个 Nacos 集群环境,有 3 个 Nacos 服务,它们的 IP 相同,端口号不同。

192.168.10.197:8848
192.168.10.197:8858
192.168.10.197:8868

 5000 字  | Nacos 架构原理①:一条注册请求会经历什么?(一)-鸿蒙开发者社区

集群环境


然后服务 A 和服务 B 都是配置了 Nacos 集群的 IP 和 端口号的,配置如下所示

spring.cloud.nacos.discovery.server-addr
  =192.168.10.197:8848,192.168.10.197:8858,192.168.10.197:8868

整体的结构如下图所示,服务 A 和 服务 B 都往 Nacos 集群进行注册。

5000 字  | Nacos 架构原理①:一条注册请求会经历什么?(一)-鸿蒙开发者社区

 服务 A 和 B 注册到集群


但是里面有一个问题:服务 A 注册时,是向所有 Nacos 节点发起注册呢?还是只向其中一个节点发起注册?如果只向一个节点注册,要向哪个节点注册呢?

 

答案:在 Client 发起注册之前,会有一个后台线程随机拿到 Nacos 集群服务列表中的一个地址。

 

Nacos 为什么会这样设计?

 

 •  这其实就是一个负载均衡的思想在里面,每个节点都均匀的分摊请求。
 •  保证高可用,当某个节点宕机后,重新拿到其他的 Nacos 节点来建立连接。


接下来我们看下服务 A 是怎么随机拿到一个 Nacos 节点的。

标签
已于2022-6-28 17:49:08修改
收藏
回复
举报
回复
    相关推荐