上文说到了服务实例的正常上下线,都是实例主动调接口完成的。但是如果实例被kill -9呢,就不会主动通知下线了。
如何处理这种情况,这个才是服务发现的重点了。
解决的办法就是 心跳+定时任务去判断,不过这里定时任务的分配也是有讲究了。
1 心跳
nacos源码分析——如何做心跳续约 中说到了,服务实例的心跳调用/clientBeat接口,会更新lastBeat为当前时间。
image.png
但是这个lastBeat时间要如何用起来呢?
2 定时任务
VirtualClusterDomain 会起个定时任务
image.png
一段时间没有收到心跳,就删除这个实例
image.png
3 定时任务的分配
上面的做法有个问题,nacos有很多服务器,每个服务器都要定时任务检查所有的服务列表吗?
如果重复的做,会有很大的资源浪费,而且如果都检查到超时了,都和leader通信说要下线,对网络的负担也比较高。
解决的办法就是 服务名hash % nacos服务器数目 ,得到其中一台 nacos服务器,如果是自己的话,就开始检查这个服务的实例列表,如果不是就跳过。
每个nacos服务器都这样去检查,自然会覆盖到所有服务的检查。
image.png image.png image.png4 server列表同步
下重点来了,每个nacos服务器数是怎么保证healthyList(server列表)是一样的呢?
解决的办法仍然是心跳:
DistroMapper 初始化的时候会启动一个ServerStatusReporter
image.pngServerStatusReporter 会向其他的nacos服务器发送心跳,证明自己是健康的
image.pngServerStatusReporter的run方法的finally会继续调用自己,这样就相当于是个定时任务了。
image.png
实际调用的接口是 /api/serverStatus,收到请求的nacos服务器就会更新自己的healthyList。
网友评论