分布式注册中心之Nacos原理分析
现在微服务在各大公司都已经是标配的季节。服务之间发现也成为了公司架构不得不考虑的一环。微服务注册中心有很多,Netfix的Eureka,携程的Apollo,Spring Cloud中Consul,阿里的Nacos...等等。虽然他们功能大概相同,原理也有些差异。今天不做比较。只分享Nacos中的注册中心实现原理。
从上图可以看到,我们的自己的服务中都会有单独的一个模块(图中client),用于和注册中心通信用的。其主要作用是,1,注册本服务的信息到注册中心;2,与注册中心保持心跳连接,上报状态等,接收服务的变动信息。当然注册中心服务要做的事情则是,收到服务注册信息保存。启动心跳检测。同时对注册中心各集群服务数据同步及选举操作。本篇我们会分别介绍客户端连接模块及注册服务核心模块。
连接端模块
在我们的服务启动同时服务注册连接模块则会初始化一些配置启动服务,通信连接的初始化等。大致会有有如下内容:
(tips:本篇尽量不带大家用翻阅源码方式来阅读,不然很枯燥)
client
启动后会将相关的IP,端口,服务名称,配置等元数据上报到注册中心。在上报的之前,会判断是否为临时服务(默认是),就会添加到定时(默认5s)发送心跳/节拍线程池(默认核心线程数为10)。上报注册实例,就是一个简单的http请求不做过多介绍。在nacos上注册的服务,分为临时和持久。对于一般的服务都是临时的,但nacos可以依赖数据库、redis等做数据持久化。这类服务则是反向嗅探机制检测其是否在线。连接端要保持心跳的服务的相关信息,默认是保存到内存(ConcurrentHashMap)中。当然这里因为调用前后关系,有可能发送心跳的请求会先于注册服务的请求到达nacos服务端。这时就会返回code=NOT_FOUND,让其走register流程。来看图
我们的服务启动后,服务中的nacos-client会将注册上报后的服务数据添加到UpdateTask,定时去请求nacos-service获取全部实例的列表信息,然后更新。这里要注意,在nacos-client与nacos-service保持心跳节拍的同时。client端会启动udpSocket监听来自nacos-service端关于服务实例信息的变更消息。具体的代码逻辑。主要在PushReceiver类。
service
首先是进入注册方法,判断service是否存在,不存在则创建。将注册serviceName,ip,namespaceId等封装成Instance。查找该服务的所有实例,并将其封装为Instances通过网络发送出去(做集群数据同步处理),先判断自己是否为leader,如果不是,则将其发送到leader让leader处理,如果是leader,则加操作锁并记录发送成功个数。具体的代码入口如下:
这里还要补充一个知识点。在nacos中,service-cluster-instance三者之间的关系,如下面官方给的图所示:
nacos服务端将上报的实例信息,集群信息等存放在map里面。这样方便快速读写及同步。当然对于nacos-client端。这些实例/集群信息是可以本地持久化的(通过配置路径),同时也可以让。nacos-client端在启动时,优先读取本地持久化注册信息。这样即使注册中心不可用时。client端也可以使用以前的注册服务信息。这种主要用在对服务错误容忍度比较高的情况下。
选举
在nacos服务之间也是存在选举的过程的,作用其实和其他分布式应用差不多。为了数据一致性做考虑nacos有两种实现。一种是简化版Raft,另外一种是Distro一致性。多主的分布式应用存在脑裂的情况。所以都要在这里面选一个leader,然后由这个选举出来的leader做数据分发/同步为准。我们以Raftl来做介绍,选举的过程有点复杂。基本上围绕RaftCore这个核心类。
每个服务之间都是有保持定时心跳的,只要发现leader挂了之后。就会进行“大选”(MasterElection),重新选择leader。这个心跳定时任务是在RaftCore.HeartBeat这个类里面操作的,其中也包括了发送Beat。
发送投票给其他nacos-server,如果成功返回的话。就会收到请求方发来的选票信息。这个时候把这个选票信息和自己的作比较。比较的有,选票数,状态,及投票给谁。如果选票数超过总服务数的一半。就直接发送停止选举事件出去。让其他人知道当选同时本机记录下来。
nacos注册中的整个架构图官网(https://nacos.io/)上都有,我在这里就不画蛇添足了。只是想说的是nacos注册中心里面有很多东西,本篇不能完整讲出来。还要你自己去翻一翻源码。
总结一下。nacos注册中心,没有采用Eureka注册中心那种双缓存服务注册表结构(copyOnlyMap+copyWriteMap)。nacos是直接就在一个map里面操作,还有默认的心跳时间、服务间隔时间也是比Eureka要短很多(eureka一般默认30s)。所以在使用的时候,感觉在服务下线失效等情况nacos会比较快一些。nacos还带有配置中心的功能,算是二合一的产品,集成进我们的项目也是很方便的。其他的优缺点待你们看了源码之后就知道了。
谢谢浏览!如有疑问,可以给我留言。