【源码分析】Nacos自动注册源码分析

@toc

服务注册(AP协议)

Nacos提供了NamingService的registerInstance方法来提供服务注册的功能。 因此只要我们能获取到这个NamingService即可完成服务的注册。

我们可以通过NacosFactory的方式来获取到NamingService以及配置中心ConfigService。

而这个注册中心的底层获取方式其实就是通过反射的方式来重建一个注册中心类。

所以我们可以按照如下方式注册并且获得注册中心的所有实例,并且监听注册中心对应实例的变化,代码如下:

java 复制代码
public class RegisterMain {
    public static void main(String[] args) throws NacosException {
        NamingService namingService = NacosFactory.createNamingService("123.249.97.220:8848");
        namingService.registerInstance("config-center","localhost",8808);
        namingService.registerInstance("config-center","localhost",8809);

        List<Instance> allInstances = namingService.getAllInstances("config-center");
        System.out.println(allInstances);
        System.out.println("---------------");
        namingService.subscribe("config-center", new EventListener() {
            @Override
            public void onEvent(Event event) {
                NamingEvent namingEvent = (NamingEvent) event;
                System.out.println("监听器监听到服务变更,服务名称为:"+namingEvent.getServiceName());
                System.out.println("监听器监听到服务变更,当前实例列表为:"+namingEvent.getInstances());
            }
        });
        while(true){

        }
    }
}

具体注册实例的方法如下,此时Nacos会根据创建的是否是短实例来选择使用grpcproxy或者httpproxy代理来注册实例。 其实大概可以看出服务注册就是向服务端发送了一个POST请求并且进行服务的注册。

服务发现(CP协议)

我们从注册中心获取服务的时候,肯定是要保证服务的一致性的,不然有些服务挂机了,你还能获取到他的实例,结果发个请求都是报错,所以服务发现选择的是CP协议,也就是Raft。 服务发现的getAllInstances其实底层也可以想到一定是和上面一套一样的流程。

我们选择httpclientproxy来查看,可以发现底层就是一个get请求

Nacos是如何整合到SpringCloudAlibaba的?

我们知道,SpringBoot基于Spring提供了一个扩展点,直接使用Spring来整合第三方是非常复杂的。 而有了SpringBoot之后,基于SpringBoot的约定优于配置的思想,我们只需要将我们需要自动加载的类编写在spring.factories文件中即可。在SpringBoot2.7之后更是改变了自动注入的方式,变得更为简单。

此时就可以看到Nacos的注册服务已经被加载了

所以上面的一套流程可以理解为:我们引入了Nacos作为注册中心之后。 SpringBoot会自动加载我们的配置类,然后这个配置类包含我们的注册中心的配置,也就是已经为我们提供好了注册方法。那么此时我们的问题就变为了,如何在当前服务启动后,自动的调用NacosServiceRegistry的register方法来将当前服务注册到注册中心去。 在上面那个bean中用于完成配置属性的封装,而在下面那个bean中则完成我们的服务的自动注册,从名称中也可以看出,Nacos自动注册服务。

我们现在重点看NacosAutoServiceRegistration这个类。 我们点开这个类中发现其继承关系如下:

重点就在于这个ApplicationListener了,我们知道,Spring在完成容器创建之后,会调用AbstractApplicationContext的refresh方法,而这个方法会注册监听器并且发布一个事件。 而这个事件就是容器刷新事件。 而这个事件最后就会触发Web容器初始化事件,从而触发对应的监听器 而这个事件发布之后,就会被我们的监听器所监听到并且执行对应的逻辑,如下: 可以发现这里的事件处理包含了一个由Nacos提供的自动注册类来完成。原因就是由于上面的Nacos的自动注册类实现了ApplicationListener 之后start方法将会进行注册 而这个register方法,就会调用其实现的具体的注册方法 此方法即NacosServiceRegistry提供的register方法,而他已经在我们引入Nacos-discovery这个依赖的时候就已经完成了自动注入。 我们知道SpringCloud其实是一种SPI思想,他只是负责提供一群接口,而其他的厂家基于这个接口来实现具体的方法,Alibaba就是其中的一种,所以可以看到NacosServiceRegistry其实就是实现了SpringCloud提供的接口而已。

相关推荐
学长毕业设计3 小时前
基于SpringBoot的公益基金管理系统(源码+文档+讲解视频)
java·spring boot·后端
东小西3 小时前
【SAA实战】第 3 篇 · 工具调用全攻略:把业务能力交给 Agent 自己调度
java·后端·spring
东小西4 小时前
【SAA实战】第 4 篇 · Agent 短期记忆:saver 让 Agent 跨轮记得住(threadId 隔离)
java·后端·spring
许彰午4 小时前
22-DataCenter报文序列化
java·低代码·架构·状态模式
2601_962065254 小时前
[MySQL] SQL优化之性能分析
java·sql·mysql
小范同学_4 小时前
JDK1.7 与 JDK1.8 HashMap 底层原理对比 + 数组并发扩容死循环详解
java·开发语言
予昊5 小时前
从零实现“在线五子棋对战“:WebSocket 实时通信 + 段位匹配
java·开发语言·网络·websocket
2601_962203515 小时前
【SpringAI入门】初识SpringAI
java
weixin_461408586 小时前
Mybatis-flex小记
java·开发语言·mybatis
2601_962177136 小时前
【MySQL篇】聚合查询,联合查询
android·java·mysql