【源码分析】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提供的接口而已。

相关推荐
盗理者8 分钟前
AI Agent 技能分享|SQL 性能诊断与优化
java·sql·spring·skill
GitLqr9 分钟前
Java 26 终于原生支持 HTTP/3 了:告别 Netty,直接用 QUIC
java·netty·http3
用户409666013175118 分钟前
Jackson 序列化:@JsonIgnore / @JsonProperty / @JsonFormat / @JsonInclude / @JsonUnwrapped 一次讲清楚
java·后端
码路漫漫20 分钟前
用了 Caffeine,消息为什么还是被处理了两次?
java
云和数据.ChenGuang29 分钟前
fastapi项目拆分实战数据模型
java·服务器·数据库·人工智能·深度学习·fastapi·强化学习
小龙报1 小时前
【优选算法】1.搜索插入位置 2.x的平方根
java·c语言·数据结构·c++·python·算法·蓝桥杯
山荷枝1 小时前
04-框架--SpringBoot
java·spring boot·后端
linux修理工1 小时前
内存占用 99% 且 Java 程序较多的优化建议
java·开发语言
weixin_460443561 小时前
企业考试系统如何对接OA、钉钉和企业微信?SSO单点登录、组织同步与权限一致性设计
java·开发语言·数据库
Sylvia33.1 小时前
篮球数据API的技术架构与工程实践:基于火星数据WebSocket实时推送体系
java·python·websocket·网络协议·架构