上章节我这边带着大家看了下Nacos的源码,针对上节课做个总结:

  • Nacos服务注册过程深度剖析
  • Nacos注册表如何防止多节点读写并发冲突
  • Nacos高并发支撑异步队列与内存队列剖析
  • Nacos心跳机制(讲了一半)

那么本节课我们将继续带着大家往下看几个点

  • Nacos服务发现源码深度剖析
  • Nacos心跳机制与服务健康检查深度剖析
  • Nacos服务变动事件发布源码剖析

1、Nacos服务发现源码深度剖析

对于服务发现,Nacos在Server端提供了一个API,由官网可以看出:

https://nacos.io/zh-cn/docs/open-api.html

Nacos的客户端通过Server端暴露的API,进行拉取服务对应的ip等信息;

还是回到源码来看。

从NacosNamingService里的getAllInstances方法进行重载的执行。

边边角角的代码先不看,if判断像是订阅,getServiceInfo()见明知意,获取服务信息

再看getServiceInfo0();这里像是从一个缓存里去取出

说明某个信息存在一个Map里,看看这个Map的结构

private final Map<String, ServiceInfo> serviceInfoMap;

这个很明显,应该就是服务信息;

判断如果从缓存中取的为空,就去做这个操作

updateServiceNow(serviceName, clusters);

去更新缓存,实际上走的还是

/instance/list

看看代码

不管什么情况,最后会走到

scheduleUpdateIfAbsent(serviceName, clusters);

里面是个定时任务UpdateTask,里面实际上是个run方法,定时获取服务端最新的数据更新到本地的任务。

所以到这,服务发现的主线源码,目前就比较清晰了。

2、Nacos心跳机制与服务健康检查深度剖析

上节课讲心跳,讲到了一个类NamingService,核心的地方是添加一个BeatInfo

那BeanInfo是什么呢?构造组装一个心跳的实体,里面存放一些信息,比如当前服务名称+ip+端口+权重+当前属于什么cluster+心跳周期等等。

最终进入addBeanInfo,这里会new一个BeatTask任务,并且把5s作为一个周期去发送心跳。

会调用sendBeat方法去向Server端发送请求,instance/beat

来看server端的这个请求,其他的边线代码不看,看主线serviceManager.registerInstance()

里面是上节课说过的,注册一个instance实例,加入到本地缓存,加入到本地缓存作为服务实例,然后会立刻开启一个任务ClientBeatProcessor,更新客户端实例的最后心跳时间

最终调用instance.setLastBeat,上节说过,会比较当前实例的最后心跳时间和当前时间,如果超过15s无响应,健康状态置为false,超过30s,会下线此实例。

那么客户端是怎么感知服务端的服务是否存在,并及时更新状态或者下线的呢?

当服务第一次注册上的时候,服务端会开启定时任务的检查

并且定时任务是5s执行一次

执行了之后就进入判断,这块不清楚的可以回顾上一章节

包括如何删除ip,也在这里面体现。

那么服务端的健康检查任务这里也讲了比较主要的过程。

3、Nacos服务变动事件发布源码剖析

        有没有考虑过一个问题,客户端会搞个定时任务定时拉取服务端的注册列表,那这么这个时间我假设是5s拉取一次,如果这个时候有服务下线或者替换,那么必须要等到下一个5s才知道这个服务不存在,这样的话实时性会跟不上,于是Nacos做了个主动推送的动作!

        先来回顾下服务发现的过程:

        在NacosNamingService.getAllInstance()中,获取客户端的服务实例缓存信息

如果获取的缓存为空,调用server获取最新的数据,updateServiceNow

然后延时执行定时任务,更新客户端的服务缓存scheduleUpdateIfAbsent(),最终进入到finally,定时执行这个任务,failCount默认值是0,Min计算当前延时的时间,和failCount最终的值进行左移运算,并和默认时间*60s做对比,这个过程中我们可以不详细解答,最坏的情况,Default_Delay*60=60s,也就是1min中会定时拉取最新数据缓存到客户端本地(这样的概率太低)。

这样显然可能会存在延时和数据不同步的问题,那么对于Nacos,做了个主动推送的机制。当服务端列表有变动的时候,服务端主动推送一个Udp请求,让客户端自己更新;

在Service.onChange中,updateIPs里面会进行发布事件

serviceChanged方法里面进行事件的发布

全文搜索下这个ServiceChangeEvent

里面有个UpdPush(),上面这么多逻辑代码都是在封装这个ackEntry,里面是一些服务端变化的信息,这个不是主线逻辑,我就不带大家看细节。

最终执行到updSocket.send()

udp相对会不稳定,和tcp不一样,所以网络丢包的时候会受到影响,当然丢了就丢了, 有变化再传一次就可以了,udp是不保证数据传输的稳定性的。那么这个策略,其实大大降低了ap架构中的数据不一致的风险。

总结下:Zookeeper中在进行服务注册的时候,发起一个长连接,比如用Nio或者

Netty,会一直占用管道,而Nacos只是发起一个http请求,发起请求后就结束了,Nacos在

1.4.x版本中是典型的短链接(当然2.0后改用gRpc长连接),而Zk采用长连接方式建立通

道,如果在客户端服务器非常非常多,会比较耗性能的,Nacos相比会轻量不少哦,Zk为了

保证服务变动的一致性,监听回调机制就会立刻通知到客户端,响应是很及时的,所以Zk保

证了Cp,Nacos有两块保证了心跳,一块是客户端的定时拉取,一块是udp反向推送,即便

udp丢失了,也有定时任务兜底。

   本节就先讲述到这,下一章讲解Nacos集群架构下的同步源码!

Nacos源码系列——第二章(Nacos核心源码主线剖析下)相关推荐

  1. 微信群控系统源码的实现原理,核心源码实现,核心框架。

    微信群控系统已经应用于各个行业,也成为大家在微信推广营销的重要工具.如今也演变出群控各种手机软件的各种系统.我们听到的主要有微信群控,淘宝群控,陌陌群控,QQ群控等等.下面我们就来简单介绍下群控系统源 ...

  2. SpringCloud Alibaba——精读Nacos+CMDB+核心源码阅读(7w字长篇)

    文章目录 Nacos 1.介绍 2.使用场景 2.1.动态配置服务 2.2.服务发现及管理 2.2.1.服务注册 2.2.2.服务心跳 2.2.3.服务同步 2.2.4.服务发现 3.环境搭建 3.1 ...

  3. RocketMQ源码系列(一) NameServer 核心源码解析

    目录 一.NameServer 介绍 二.NameServer 功能列表 三.NameServer 架构分析 四.NameServer 工程目录解析 五.NameServer 启动流程分析 1)  创 ...

  4. 面试官系统精讲Java源码及大厂真题 - 09 TreeMap 和 LinkedHashMap 核心源码解析

    09 TreeMap 和 LinkedHashMap 核心源码解析 更新时间:2019-09-05 10:15:03 人的影响短暂而微弱,书的影响则广泛而深远. --普希金 引导语 在熟悉 HashM ...

  5. 怎么用matlab画无差别曲线,MATLAB系列第二章初等模型.ppt

    <MATLAB系列第二章初等模型.ppt>由会员分享,可在线阅读,更多相关<MATLAB系列第二章初等模型.ppt(68页珍藏版)>请在人人文库网上搜索. 1.第二章 初等模型 ...

  6. 【源码阅读计划】浅析 Java 线程池工作原理及核心源码

    [源码阅读计划]浅析 Java 线程池工作原理及核心源码 为什么要用线程池? 线程池的设计 线程池如何维护自身状态? 线程池如何管理任务? execute函数执行过程(分配) getTask 函数(获 ...

  7. Android框架源码分析——从设计模式角度看 Retrofit 核心源码

    Android框架源码分析--从设计模式角度看 Retrofit 核心源码 Retrofit中用到了许多常见的设计模式:代理模式.外观模式.构建者模式等.我们将从这三种设计模式入手,分析 Retrof ...

  8. 蓝桥杯算法竞赛系列第二章——深入理解重难点之递归(上)

    铁汁们,递归(下)已经更新咯,欢迎铁汁们批评指正. 蓝桥杯算法竞赛系列第二章--深入理解重难点之递归(下)_安然无虞的博客-CSDN博客 目录 一.递归是什么? 二.如何理解"递归" ...

  9. Netty 核心源码解析

    Netty 第一讲:Netty 架构与原理 本文是<Netty 三讲>的第二讲:Netty 核心源码解析(部分),大纲如下: 前言 1. Netty 服务端启动过程源码剖析 1.1. 执行 ...

最新文章

  1. 量子力学工具箱再添利器—科学家提出高效驱动微型引擎概念
  2. Caused by: java.lang.ClassNotFoundException: javax.persistence.Entity
  3. BZOJ2301: [HAOI2011]Problem b
  4. linux下remove函数
  5. Java 判断字符串第一位和最后一位,并截取
  6. Codeforces Round #506 (Div. 3) - E. Tree with Small Distances
  7. Spring REST:异常处理卷。 3
  8. 高清壁纸|海贼王漫画名场面
  9. brighthouse mysql_MySQL 数据库中的数据页合并-爱可生
  10. linux下qemu共享文件夹,QEMU Windows来宾和Linux主机之间的共享文件夹
  11. 如何在乌版图系统添加拼音输入法!
  12. ThinkPHP2.1 增加PHPCMS模板引擎,支持PC标签(get,json)
  13. 冒险岛079单机/小范围联机游戏搭建
  14. 弗洛伊德的兔子与乌龟
  15. (imooc笔记)短除法计算算 十进制 八进制 十六进制
  16. 在线2进制8进制10进制16进制进制转换工具
  17. GUI 图片显示(SDL 多媒体开发库)——基于 rt-smart 微内核操作系统
  18. ufs 固态硬盘_东芝首发UFS 3.0闪存:性能媲美高端PC 固态硬盘
  19. 金融应用:信用卡号的合法性验证
  20. 微信淘宝客引流的正确玩法

热门文章

  1. 勒索软件层出不穷,Veeam “3-2-1-1-0”助力构建数据防护
  2. DPU加持下的阿里云如何做加密计算?
  3. TPAMI 2021 | 深度赋智AutoDL系列竞赛世界冠军方案首次公开
  4. 操纵神经元构造后门,腾讯朱雀实验室披露AI模型新型攻击手法
  5. “数学不好,干啥都不行!”骨灰级程序员:其实你们都是瞎努力!
  6. ELECTRA:超越BERT,2019年最佳NLP预训练模型
  7. 高通投资商汤,是因为手机刷脸市场吗?阿里巴巴再砸AI芯片,弄啥咧 | AI三分钟
  8. 观点 | 哈哈,TensorFlow被吐槽了吧
  9. 重磅 | 最全PPT实录!英伟达发布可编程AI推理加速器TensorRT
  10. 再见了!面试八股文。。。