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

相关推荐
掐指一算乀缺钱10 分钟前
SpringBoot 数据库表结构文档生成
java·数据库·spring boot·后端·spring
晚睡早起₍˄·͈༝·͈˄*₎◞ ̑̑15 分钟前
苍穹外卖学习笔记(七)
java·windows·笔记·学习·mybatis
就这个java爽!21 分钟前
JAVA网络编程【基于TCP和UDP协议】超详细!!!
java·开发语言·网络·tcp/ip·udp·eclipse·idea
一叶飘零_sweeeet25 分钟前
为什么 Feign 要用 HTTP 而不是 RPC?
java·网络协议·http·spring cloud·rpc·feign
懒洋洋大魔王1 小时前
7.Java高级编程 多线程
java·开发语言·jvm
茶馆大橘1 小时前
【黑马点评】已解决java.lang.NullPointerException异常
java·开发语言
星辰@Sea1 小时前
服务注册中心对比及使用场景分析
java·云原生
马剑威(威哥爱编程)1 小时前
除了递归算法,要如何优化实现文件搜索功能
java·开发语言·算法·递归算法·威哥爱编程·memoization
bug菌¹1 小时前
滚雪球学SpringCloud[4.1讲]: Spring Cloud Gateway详解
java·spring cloud·微服务
bug菌¹1 小时前
滚雪球学SpringCloud[4.2讲]: Zuul:Netflix API Gateway详解
spring·spring cloud·gateway