目录
- 1 快速入门使用
- 2 源码解析
- 2.1 环境准备
- 2.2 查看实例列表源码分析
- 2.3 nacos与zk的不同 :
- 2.4 nacos服务发现
- 2.5 nacos的心跳机制和服务健康检查的逻辑
1 快速入门使用
SpringCloud Nacos配置中心:https://blog.csdn.net/ZGL_cyy/article/details/113621565
SpringCloud Nacos实战应用: https://blog.csdn.net/ZGL_cyy/article/details/130873488
2 源码解析
2.1 环境准备
下载源码或者安装包
你可以通过源码和发行包两种方式来获取 Nacos。
从 Github 上下载源码方式
git clone https://github.com/alibaba/nacos.git
cd nacos/
mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U
ls -al distribution/target/
// change the $version to your actual path
cd distribution/target/nacos-server-$version/nacos/bin
nacos提供了一些api, 其中有一个api就是用来发现服务的
https://nacos.io/zh-cn/docs/open-api.html
2.2 查看实例列表源码分析
nacos通过springboot的自动装配, 在项目启动时候通过nacos提供的api去nacos服务端拉取服务
查看源码 :
进入NacosDiscoveryAutoConfiguration类查看, 看一下自动装配的源码
进入this.namingService().selectInstances方法
为什么springboot刚启动, 第一次调用注册的服务速度会慢? 就是因为nacos的服务是懒加载的, 我们只有请求了一次服务, nacos才会去服务端将所有注册的服务获取到(上面if中的逻辑), 当我们第二次调用时, 已经获取到服务了, 只需要调用就可以了, 所有第一次请求的速度比较慢
2.3 nacos与zk的不同 :
总所周知, zk底层采用netty长连接的方式发送心跳, 来判断服务端的服务是否挂掉, 而nacos则是采用短连接 + 周期性线程池(请求服务列表api)的方式来判断服务是否挂掉
上面已经说了nacos服务发现的原理, 让我们来看看第一次服务发现 与周期性服务发现的代码实现
2.4 nacos服务发现
服务第一次发现 :
周期性服务发现 :
进入this.scheduleUpdateIfAbsent方法
进入this.updateService(this.serviceName, this.clusters);
服务发现就此结束
2.5 nacos的心跳机制和服务健康检查的逻辑
接下来一起看一下nacos的心跳机制和服务健康检查的逻辑
从nacos的服务注册开始查看(注册的源码分析上一篇有所讲解), nacos的客户端服务注册过程中有这样一行代码
分别进入两个方法
此次是一个延时线程池, 过了5秒之后,去执行run方法, 接下来进入run方法
进入serverProxy.sendBeat方法
发送实例心跳, nacos在服务注册的时候, 就会通过线程池延时五秒发送心跳, 此处只发送了一次心跳, 按照我们的理解, 应该是持续发送心跳的, 那么接下来继续看run方法中的另一个方法
通过反复的执行run方法, 来达到每隔5s中发送一次心跳的功能
到此nacos的客服端服务注册完成, 接下来查看一下nacos服务端是如何持续的进行心跳检测的 :
由于方法层次太多就不贴图了, 方法调用路径
InstanceController.register ->
getInstanceOperator().registerInstance(namespaceId, serviceName, instance); -> InstanceOperatorServiceImpl.registerInstance -> serviceManager.registerInstance(namespaceId, serviceName, coreInstance); -> createEmptyService(namespaceId, serviceName, instance.isEphemeral()); -> createServiceIfAbsent(namespaceId, serviceName, local, null); -> putServiceAndInit(service); ->
service.init(); ->
最终进入init()方法
此处又可以看见一个线程池, 进入scheduleCheck方法
接下来进入run方法查看 (他的子类ClientBeatCheckTask类中)
到此为止, 发送心跳和服务的健康状态检查源代码查看完毕
现在大家可能有这样一个疑问, 如果一个服务新注册到nacos服务端, 那么服务发现者们只有在5s之后拉取服务的时候才会发现有新的服务, 那么就会有一个5s的延时发现服务, 其实这样是可以接受的, 但是nacos对此也进行了优化, 如果一个新的服务注册到nacos服务端, 注册完成之后,nacos会利用事件发布, 给所有的服务发现者发送事件, 让服务发现者可以更快的发现服务