这是悟空的第 144 篇原创文章 官网:www.passjava.cn 大家好,我是悟空呀。 前言上篇我们讲解了如何使用 Nacos 作为注册中心和配置中心。 这次我们来聊下 Nacos 的注册服务的底层原理。 Nacos 作为注册中心,用来接收客户端(服务实例)发起的注册请求,并将注册信息存放到注册中心进行管理。
知识点预告先上一张整体的流程图:
这些知识点里面还有很多细节,我会通过画图 + 源码剖析的方式给大家解答。如果遇到源码看不太懂的地方,可以多看下我画的图,然后翻下源码,对照着一起看。 小 Tip:本文使用的 Nacos 版本:2.0.4。 一、源头:发起注册1.1 阅读源码的小技巧上篇我们讲到加上一个注解
告诉大家一个看源码的小技巧,拿到源码后,不是直接各个文件都看一篇,而是先看源码中带的 example 文件夹。如下图所示,找到 example 的 App 类,里面就有发起注册的实例代码。如下图所示: 当然,我们也可以通过官网给的 curl 命令发起 HTTP 请求:
留个问题:我们都是加一个 Nacos 注解 1.2 发起注册的流程图先来看一下代码的流程图: 跟着这个流程图,我们 debug 来看下。 1.3 组装注册的实例信息入口的核心代码如下图所示,它会组装注册的 通过代码调试,我们可以看到里面的实例信息长这样: 1.4 组装注册请求 request发起注册的核心方法是 doRegisterService(),组装的 request 如下图所示,里面有之前组装的实例信息 instance,还有指定的 namespace(Nacos 的命名空间)、serviceName(服务名),groupName(Nacos 的分组)。 1.5 发起远程调用requestToServer() 方法里面会调用 RpcClient 的 request() 方法:
就是向 Nacos 发起远程调用,如果是 Nacos 集群,则是向集群中的某个 Nacos 节点发起远程调用。 接下来我们看下客户端是如何选择一个 Nacos 节点进行注册的。 二、集群环境:分布式的前提如果是 Nacos 集群环境,客户端会随机选择一个 Nacos 节点发起注册。 2.1 搭建好一套Nacos 集群环境为了讲解客户端是如何注册到 Nacos 集群环境的底层原理,我在本地搭建了一个 Nacos 集群环境,有 3 个 Nacos 服务,它们的 IP 相同,端口号不同。
然后服务 A 和服务 B 都是配置了 Nacos 集群的 IP 和 端口号的,配置如下所示
整体的结构如下图所示,服务 A 和 服务 B 都往 Nacos 集群进行注册。 但是里面有一个问题:服务 A 注册时,是向所有 Nacos 节点发起注册呢?还是只向其中一个节点发起注册?如果只向一个节点注册,要向哪个节点注册呢?
Nacos 为什么会这样设计?
接下来我们看下服务 A 是怎么随机拿到一个 Nacos 节点的。 三、随机节点:平等的世界我们来看下客户端是如何随机选择一个节点的,流程图如下: 那么如何找到这些代码逻辑呢?思路是怎么样的? 我们之前讲过,RpcClient 会发起 request 请求,用的是和 Nacos 建立
这个
而连接的信息是通过参数 serverInfo 传进去的,所以我们再看下 serverInfo 在哪里赋值的。 这个 nextRpcServer() 方法里面会拿到一个随机的 Nacos 地址:
小结:客户端生成一个随机数,然后通过这个随机数从 Nacos 服务列表中拿到一个 Nacos 服务地址返回给客户端,然后客户端通过这个地址和 Nacos 服务建立连接。Nacos 服务列表中的节点都是平等的,随机拿到的任何一个节点都是可以用来发起调用的。 四、路由转发:不是我的菜4.1 发起和转发请求的流程为了演示发起注册的流程,我在这里模拟了一个注册请求。 用的是 curl 命令,对 Nacos 节点(127.0.0.1:8848)发起注册请求:
请求 URL:/nacos/v1/ns/instance 请求参数:
之前我们讲到,Nacos 的有多个节点可以分别处理请求,当节点发现这个请求不是属于自己的,就会进行转发。 如下图所示: 服务 A 随机选择一个 Nacos 节点(图中为 Nacos1)发起注册请求,请求参数中包含了实例信息,Nacos 1 根据实例信息 hash + 取模拿到正确的节点,如果不属于自己,则将请求转发给其他节点(图中为 Nacos2) 那么路由转发的细节是怎么样的?这个就涉及到 Distro 协议了,我们接着往下看。 4.1 路由转发的逻辑其实 Nacos 节点的路由转发逻辑比较简单,先来看下流程图: 步骤如下:
我没看懂的点:我这里启动了三个 Nacos 节点,如下图所示的 三个 Running 节点。但是为什么 Nacos 的 ServersList 会多了一个 192.168.10.197:8848的节点? 4.2 路由转发源码分析入口文件是 DistroFilter.java:
请求会先到 DistroFilter 类的 doFilter() 方法,拿到正确的节点地址后,将请求转发出去。 获取需要转发节点地址的代码如下:
不论是自己处理注册请求还是转发给其他节点来处理,都会把实例信息存储起来,那么是如何进行存储的? 五、处理请求:快到碗里来Nacos 目前有两个版本,v1 和 v2,如果是 v1,则是 instanceController 来处理注册请求,否则用 instanceControllerV2。本篇我们只讲解 v1 版本是怎么处理请求的。 先上流程图: 测试用的发起注册的命令:
核心代码就是这个: 首先有一个 synchronized 锁,然后执行 put 操作将临时的实例信息存放起来,所以重点看下 这个 consistencyService.put() 方法做了什么事情。 先看下源码:
这里面做了三件事情:
注意:针对第二点和第三点,属于 Distro 一致性协议的一部分,里面的内容还比较多,我们放到下一讲专门来讲。 下一讲知识点预告:
六、总结本文通过发起一条注册请求,讲解了 Nacos 客户端如何随机选择节点、Nacos Server 如何将请求进行路由转发、Nacos Server 如何存储注册实例。 另外本文用到了集群环境,关于如何搭建和 debug 集群环境,感兴趣的可以留言,后续补上这部分的讲解。 一条注册请求的核心流程: 下一篇预告:Nacos 的一致性协议 Distro 协议,揭秘 AP 架构。 我是悟空,期待与你一起打怪升级变强!我们下期见。 推荐阅读:《SpringCloud 底层架构剖析》 参考资料:Nacos 官网 - END - |
|
来自: 昵称10087950 > 《JAVA》