文章目录
一. 问题背景
前面研究了Day1——Nacos自动服务注册原理(一),但是感觉研究得太笼统太浅了,今天继续深入了解一下对于SpringBoot应用Nacos是怎么完成自动服务注册的?
二. 前言
- yml中配置nacos的ip地址,需要写绝对地址,不要因为是localhost就写127.0.0.1。否则会有问题
- 关于本篇博客,还是推荐了解自动服务注册的流程即可,不必纠结在源码实现细节,毕竟源码会因springboot的版本不同而不同。
- 本文将从nacos客户端、服务端来讲解自动服务注册的流程
- 前往gitee下载nacos客户端源码工程用来研究nacos自动服务注册的源码,前往nacos的github页面下载,用来启动nacos
三. 回顾(重要)
首先对上篇Day1——Nacos自动服务注册原理(一)做一个回顾并总结,如下:
四. 源码分析nacos客户端自动服务注册的流程
我们从NacosServiceRegistry的register()方法进行切入,如下:
总结:nacos客户端自动注册服务,其实就是利用类似restTemplate发送请求给nacos服务端
五. 源码分析nacos服务端处理自动服务注册的流程
5.1 理清思路(重要)
前面分析了nacos客户端自动服务注册的源码,其实就是发送请求。那么服务端如何处理请求呢?我们一般处理请求是用controller,nacos服务端是否也是这样呢?客户端发送请求,服务端用controller处理请求。如果是如此的话,那么controller的RequestMapping是怎样的呢?
联想到nacos客户端发送的POST方式的url,只要发送如下url,就可以注册服务:
curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=example&ip=127.0.0.1&port=8080'
可以想到controller的RequestMapping大概就是v1/ns/instance
因此我们只需在nacos项目中搜索v1/ns/instance
就大概可以搜到那个controller了,但是url可能存在拼接的原因,不一定就是完整的v1/ns/instance
。因此使用actuator来监控断点。
5.2 找出处理服务注册的controller
我们使用actuator来监控断点。
引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
在nacos服务端配置:
#*************** CMDB Module Related Configurations ***************#
### The interval to dump external CMDB in seconds:
nacos.cmdb.dumpTaskInterval=3600
### The interval of polling data change event in seconds:
nacos.cmdb.eventTaskInterval=10
### The interval of loading labels in seconds:
nacos.cmdb.labelTaskInterval=300
### If turn on data loading task:
nacos.cmdb.loadDataAtStart=false
#*************** Metrics Related Configurations ***************#
### Metrics for prometheus
#management.endpoints.web.exposure.include=*
### Metrics for elastic search
management.metrics.export.elastic.enabled=false
#management.metrics.export.elastic.host=http://localhost:9200
### Metrics for influx
management.endpoints.web.base-path=/manage
management.metrics.export.influx.enabled=false
management.endpoints.web.exposure.include=*
management.endpoint.shutdown.enabled=true
启动nacos,在浏览器输入http://192.168.0.106:8488/nacos/manage/mappings
(其中http://192.168.0.106:8488/nacos/
是你的nacos地址),ctrl+f搜索v1/ns/instance
,如下:
总结:nacos服务端用InstanceController的register方法来处理服务注册,请求方式是post方式
5.3 流程分析
总结:服务端其实拿到服务,然后存到Map里面
六. Nacos是如何实例化与自动服务注册有关的类的?
由前面的回顾图中我们知道Nacos针对Spring Cloud commons模块的接口标准做了整合,核心的是NacosAutoServiceRegistration类以及NacosServiceRegistry类。那么这两个类是如何实例化并交给容器管理的? 我们继续研究
6.1 如何被实例化的?
开启nacos自动服务注册,只需有三步:引入spring-cloud-starter-alibaba-nacos-discovery
依赖;yml文件配置nacos相关配置项;在SpringBoot启动类加@EnableDiscoveryClient
;
我们继续看看@EnableDiscoveryClient
里面有什么,如下:
由上图看到,AutoServiceRegistrationConfiguration会被实例化,我们全局搜一下这个类相关的类,如下:
至此NacosAutoServiceRegistration
和NacosServiceRegistry
实例化完毕。
总结:当springboot启动完后会发布这个事件,然后就被NacosAutoServiceRegistration
监听器监听到了。然后会执行onApplicationEvent()
方法->bind()
方法->start()
方法->register()
方法,最终调用到NacosServiceRegistry
的register()
方法
七. 总结
- 必须注意spring cloud commons对服务注册做了标准接口,nacos对这个标准做了整合以及实现
- nacos客户端其实就是发送请求给服务端,nacos服务端将服务注册并检查客户端的健康状态。
- 服务的自动注册其实是利用了Spring的
WebServerInitializedEvent
事件,最终由NamingService
完成服务注册工作。