nacos 服务注册和发现原理
泛域名ssl证书 239元1年送1个月、单域名39元1年,Sectigo(原Comodo证书)全球可信证书,强大的兼容性,高度安全性,如有问题7天内可退、可开发票
加微信VX 18718058521 备注SSL证书
【腾讯云】2核2G4M云服务器新老同享99元/年,续费同价
服务注册原理:
服务(项目)启动时,根据spring-cloud-commons中spring.factories的配置,自动装配了类AutoServiceRegistrationAutoConfiguration。
AutoServiceRegistrationAutoConfiguration类中注入了类AutoServiceRegistration,其最终实现子类实现了Spring的监听器。
根据监听器,执行了服务注册方法。而这个服务注册方法则是调用了NacosServiceRegistry的register()方法。
该方法主要调用的是Nacos Client SDK中的NamingService下的registerInstance()方法完成服务的注册。
registerInstance()方法主要做两件事:服务实例的健康监测和实例的注册。
通过schedule()方法定时的发送数据包,检测实例的健康。
若健康监测通过,调用registerService()方法,通过OpenAPI方式执行服务注册,其中将实例Instance的相关信息存储到HashMap中。
服务发现原理:
Nacos的服务发现,一般是通过订阅的形式来获取服务数据。
而通过订阅的方式,则是从本地的服务注册列表中获取(可以理解为缓存)。相反,如果不订阅,那么服务的信息将会从Nacos服务端获取,这时候就需要对应的服务是健康的。(宕机就不能使用了)
在代码设计上,通过Map来存放实例数据,key为实例名称,value为实例的相关信息数据(ServiceInfo对象)。
最后,服务发现的流程就是:
以调用远程接口(OpenFeign)为例,当执行远程调用时,需要经过服务发现的过程。
服务发现先执行NacosServerList类中的getServers()方法,根据远程调用接口上@FeignClient中的属性作为serviceId传入NacosNamingService.selectInstances()方法中进行调用。
根据subscribe的值来决定服务是从本地注册列表中获取还是从Nacos服务端中获取。
以本地注册列表为例,通过调用HostReactor.getServiceInfo()来获取服务的信息(serviceInfo),Nacos本地注册列表由3个Map来共同维护。
本地Map–>serviceInfoMap,
更新Map–>updatingMap
异步更新结果Map–>futureMap,
最终的结果从serviceInfoMap当中获取。
HostReactor类中的getServiceInfo()方法通过this.scheduleUpdateIfAbsent() 方法和updateServiceNow()方法实现服务的定时更新和立刻更新。
而对于scheduleUpdateIfAbsent()方法,则通过线程池来进行异步的更新,将回调的结果(Future)保存到futureMap中,并且发生提交线程任务时,还负责更新本地注册列表中的数据。