⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 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的逻辑一定会执行。。