总结nacos自动服务注册

一. 问题背景

研究了nacos自动服务注册源码,关于nacos服务端集群原理尚未搞懂,因此这个总结有不足之处。看的时候要了解各个组件之间的关系,这样更容易懂

参考自:【java进阶课程】玩转spring cloud alibaba易如反掌,从入门到精通nacos

二. 源码

  1. nacos源码:前往nacos的gitee页面下载,用来启动nacos的
  2. springboot工程:前往gitee页面下载,用来研究nacos自动服务注册的源码

三. 架构总结

下图的下载地址: 下载由于csdn官方原因,免费下载的方式只有关注本作者才能下载,我也不太想这样,希望理解

可右击“在新标签打开”查看大图,如下:
在这里插入图片描述

四. 调用流程总结

下图的下载地址: 下载由于csdn官方原因,免费下载的方式只有关注本作者才能下载,我也不太想这样,希望理解

可右击“在新标签打开”查看大图,如下:
在这里插入图片描述

五. distro协议总结

前言:根据ACP原则,nacos有2中模式:AP模式(高可用,弱一致性,nacos采用distro协议);CP模式(强一致性,nacos采用raft协议,暂时没研究raft协议)

注:C代表Client客户端;S代表Server服务端

  1. 客户端与服务端有2个重要的交互:服务注册心跳发送

  2. C向S注册一个服务,继而以执行任务的模式向S发送一次心跳,心跳包需要带上C的全部信息。站在C的角度S集群所有节点都是对等的,所以请求S集群中节点是随机的。

  3. C如果请求失败,则换一个S的节点重新发送请求。

  4. S集群任意一个节点都存储所有数据,但每个节点只负责其中一部分服务,在接收到C的“写”(注册、心跳、下线等等)请求后,S节点判断请求的任务是否为自己负责,如果是,则处理;否则交由负责的节点处理。

  5. distro判断一个请求是由S集群中哪个节点负责用的是一个非常简单的hash算法==(int target = distroHash(serviceName) % healthyList.size()设S某个节点挂了,则都会重新计算一遍,非常蛋疼,其实可以采用一致性的hash算法==;这样只会重新计算分发到挂掉的机器上,不会全部计算。

  6. 每个S节点主动发送健康检查到其他节点,响应的节点被该节点视为健康节点

  7. S接收到C的心跳后,如果该服务不存在,则将该心跳请求当作注册请求来处理。(出现服务不存在的原因是:S在15内收不到C的心跳,S标记C为不健康节点,再过15s仍收不到C的心跳,那么S将C剔除了。其实可能是C发送的心跳包在网络中滞留太久了,导致无法及时发送给S。)

  8. S如果15s内没有收到C心跳,则把该C标记为不健康;如果30s没有收到心跳,则下线该C

  9. 负责的S节点接收到C的“写”(服务注册、心跳等)请求后,将数据写入后即返回,S后台异步将数据同步给其他S节点(开启线程做服务端的数据一致性)

  10. S节点在收到读请求后直接从本机获取后返回,不管数据是否为最新

com.alibaba.nacos.naming.consistency.ephemeral.distro.DistroConsistencyServiceImpl#put    taskDispatcher.addTask(key);
  1. 任意一个S节点启动的时候都会去判断S集群中的节点是否大于1,如果大于1,则执行远程同步(服务端的数据一致性),否则让线程睡眠1s继续判断集群节点是否大于1

  2. C在启动的时候会建立一个UDP接收方(初始化HostReactor)。C向S获取服务列表的时候,S会收到C的UDP信息(然后S会将此C添加到订阅队列里面),以后当S更新的时候会把更新信息推送给C

  3. C在第一次获取服务列表的时候,会开启一个任务每隔10s秒钟(这个10s由S决定的)去S拿一次最新的服务列表

六. 收获

  1. 关于注册中心的功能,大部分底层都是客户端发送一个http请求,服务端接收请求并进行处理。

  2. 关于多线程的应用场景:在阅读nacos服务注册的相关源码时,大部分都是用多线程来开启一个任务,用来做一些事情,==比如开启一个线程定时发送心跳,定时发送udp检查实例的健康状态。==以前了解多线程应用场景大都是用来下载文件。有一种对多线程新的认知

  3. 有必要了解一下通信协议,比如去了解netty框架、线程池

猜你喜欢

转载自blog.csdn.net/qq_40634846/article/details/112234798