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

相关推荐
m0_5719575838 分钟前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
魔道不误砍柴功3 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2343 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨3 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
测开小菜鸟4 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity5 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天5 小时前
java的threadlocal为何内存泄漏
java
caridle5 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
^velpro^6 小时前
数据库连接池的创建
java·开发语言·数据库
苹果醋36 小时前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx