《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》

摘要: 原创出处 https://www.jianshu.com/p/661498752ab9 「黄云斌」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

上文说到了服务实例的正常上下线,都是实例主动调接口完成的。但是如果实例被kill -9呢,就不会主动通知下线了。

如何处理这种情况,这个才是服务发现的重点了。

解决的办法就是 心跳+定时任务去判断,不过这里定时任务的分配也是有讲究了。


1 心跳

nacos源码分析——如何做心跳续约 中说到了,服务实例的心跳调用/clientBeat接口,会更新lastBeat为当前时间。

但是这个lastBeat时间要如何用起来呢?


2 定时任务

VirtualClusterDomain 会起个定时任务

一段时间没有收到心跳,就删除这个实例

3 定时任务的分配

上面的做法有个问题,nacos有很多服务器,每个服务器都要定时任务检查所有的服务列表吗?

如果重复的做,会有很大的资源浪费,而且如果都检查到超时了,都和leader通信说要下线,对网络的负担也比较高。

解决的办法就是 服务名hash % nacos服务器数目 ,得到其中一台 nacos服务器,如果是自己的话,就开始检查这个服务的实例列表,如果不是就跳过。

每个nacos服务器都这样去检查,自然会覆盖到所有服务的检查。


4 server列表同步

下重点来了,每个nacos服务器数是怎么保证healthyList(server列表)是一样的呢?

解决的办法仍然是心跳:

DistroMapper 初始化的时候会启动一个ServerStatusReporter

ServerStatusReporter 会向其他的nacos服务器发送心跳,证明自己是健康的

ServerStatusReporter的run方法的finally会继续调用自己,这样就相当于是个定时任务了。

实际调用的接口是 /api/serverStatus,收到请求的nacos服务器就会更新自己的healthyList。

如果一直没收到其他nacos服务器的心跳信息呢,这里就有个神奇的逻辑了:

ServerStatusReporter是会模拟发送心跳给自己,保证healthyList的逻辑一定会执行。。

文章目录
  1. 1. 上文说到了服务实例的正常上下线,都是实例主动调接口完成的。但是如果实例被kill -9呢,就不会主动通知下线了。
  • 如何处理这种情况,这个才是服务发现的重点了。
    1. 1. 解决的办法就是 心跳+定时任务去判断,不过这里定时任务的分配也是有讲究了。
    2. 2. 1 心跳
      1. 2.1. 但是这个lastBeat时间要如何用起来呢?
    3. 3. 2 定时任务
      1. 3.1. 一段时间没有收到心跳,就删除这个实例
    4. 4. 3 定时任务的分配
    5. 5. 解决的办法就是 服务名hash % nacos服务器数目 ,得到其中一台 nacos服务器,如果是自己的话,就开始检查这个服务的实例列表,如果不是就跳过。
    6. 6. 4 server列表同步
    7. 7. ServerStatusReporter 会向其他的nacos服务器发送心跳,证明自己是健康的
    8. 8. 如果一直没收到其他nacos服务器的心跳信息呢,这里就有个神奇的逻辑了:
    9. 9. ServerStatusReporter是会模拟发送心跳给自己,保证healthyList的逻辑一定会执行。。