服务器的心跳协议,Nacos服务端心跳续约

阅读: 评论:0

服务器的心跳协议,Nacos服务端心跳续约

服务器的心跳协议,Nacos服务端心跳续约

先看下服务端处理的InstanceController概览图:

InstanceController概览图

当客户端调用reqApi向服务器发送Http PUT心跳请求,URI是/nacos/v1/ns/instance/beat,对应的controller就是InstanceController的beat方法。beat方法首先检查Instance是否存在,Instance不存在的情况:比如客户端超过30秒没有向服务器发送心跳,这时服务端会删除这个实例,30秒后再发送心跳时就会出现Instance不存在的情况。

说回来,如果实例不存在,并且客户端也没有发送BeatInfo包,这时会返回给客户端一个实例不存在的错误;如果Instance实例不存在,但客户端发送了BeatInfo包,这时能拿到BeatInfo里的信息,beat方法就会创建Instance对象,并调用ServiceManager类的registerInstance方法注册服务实例。

这个BeatInfo包就是客户端发送心跳时判断的参数:Light_Beat_Enabled,如果这个参数是false就发送,默认值就是false,这个逻辑在讲客户端时讲过一遍了。

我们具体看下InstanceController类beat方法代码:

InstanceController类beat方法-1

InstanceController类beat方法-2

InstanceController类beat方法-3

ServiceManager类getInstance方法涉及到Service、Cluster、Instance的内存数据结构,服务注册就是把数据写到这几个类的关键变量中,服务发现也是从这几个类的变量中查找,所以这几个类的数据结构非常重要。

首先,Service服务是存储在ServiceManager类的serviceMap变量里,类型是:

Map> serviceMap = new ConcurrentHashMap<>();

Map里key含义如下:Map(namespace, Map(group::serviceName, Service))

serviceMap是个双层Map结构,先用namespace拿到该名字空间的所有Service,再用serviceName拿到Service对象。

Cluster集群存在Service类的clusterMap变量里,类型是:Map clusterMap = new HashMap<>();Map里key含义:Map;clusterMap中存储该service所有的集群,使用clustername可以直接拿到Cluster对象实例。

Instance分为临时服务和永久服务,是分开存的,在Cluster类中的2个变量里:

Set persistentInstances = new HashSet<>()   //永久服务实例

Set ephemeralInstances = new HashSet<>()  //临时服务实例

persistentInstances中是该集群中所有永久服务的Instance的集合;ephemeralInstances 是该集合中所有临时服务的Instance的集合,Instance对象是对应Ip、port、healthy等属性。

ServiceManager类getInstance就是从上面几个变量结构中查找到具体的Instance实例,如果数据结构中没有就创建一个Instance对象,然后调用ServiceManager类的registerInstance方法注册实例,registerInstance注册实例就是向那几个数据结构Map中塞数据,然后把注册数据再同步到nacos服务器集群其他节点。这个registerInstance注册服务逻辑后面会介绍。

接着看InstanceController类beat方法最后一段代码:

InstanceController类beat方法-4

首先组装心跳基本属性到clientBeat对象,传给Service的processClientBeat方法,processClientBeat拿到ip和port就可以找到Instance,然后做该Instance的心跳续期。下面是给客户端设置心跳间隔时间和是否发送心跳BeatInfo对象,这2个属性设置后会覆盖默认属性(心跳间隔默认是5秒,默认发送BeatInfo),设置后返回给客户端后,客户端就按这个最新的属性设置发送心跳。之前在客户端上报心跳逻辑时,也详细讲过这2个属性。上面代码可以看出设置这2个属性的值是从nacos控制台拿到的,用户在控制台上可以设置这2个属性的metadata元数据,这个之后可以看下怎么在控制台设置这些元数据。

好了,InstanceController类beat方法我们说完了。

我们接着看下Service类的处理心跳方法processClientBeat,这个是服务端心跳的核心逻辑,见下图,只剩下最后这一个了:

InstanceController类beat流程

看下processClientBeat代码:

processClientBeat方法

这段代码很简单,创建一个处理心跳的处理器任务ClientBeatProcessor,然后扔到线程池中立即执行,见scheduleNow方法。我们看下ClientBeatProcessor这个线程怎么处理心跳的?

先看第一段,取出该服务的必要属性,主要是取出该服务的所有Instance,后面做遍历找要上报心跳的Instance。

ClientBeatProcessor线程-1

再看最后一段:

ClientBeatProcessor线程-2

这段是心跳服务续约的核心逻辑,先在所有Instance里找到匹配上报心跳的Instance,然后设置该实例的最后上报时间,nacos就是根据这个属性判断15秒心跳超时、30秒删除实例。然后刷新下实例的健康属性,比如上次心跳15超时,这个health属性会被设置成false,这次上报后会重置成健康true。最后调用PushService组件,该组件是通过udp协议向客户端推送服务变更信息,这个后面有详细说明。

本文发布于:2024-01-31 01:17:37,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170663505824301.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:服务端   协议   服务器   Nacos
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23