nacos源码分析-服务注册

Nacos server: 2.4.3

JDK: 1.8

spring-cloud-starter-alibaba-nacos-discovery-2021.0.5.0.jar

Maven: 3.8.8

我的Nacos仓库:https://github.com/wangyong5609/nacos,分支:2.4.3-analysis

一、Nacos简介

Nacos 是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台

image.png

目前主要关注 Nacos 服务注册与发现相关的内容

  • 服务提供者在启动时会向Nacos注册中心发送注册请求,包括服务名称、IP地址、端口号等信息。
  • Nacos服务端接收到注册请求后,将服务实例信息存储在注册中心的数据库中,并缓存到内存中以便快速查询。
  • 注册成功后,服务提供者会定期向Nacos发送心跳请求,以表明服务实例仍在运行中。
  • 服务消费者从服务注册中心发现并调用服务。

img

二、服务注册原理

1.客户端请求原理图

Processon 地址:https://www.processon.com/diagraming/672d9c0ca8011b320f4a064c

image-20241108135709194

简单来说就是,项目引入 spring-cloud-starter-alibaba-nacos-discovery 以后,利用Spring的自动装配,在它的spring.facotries中加载了 NacosServiceRegistryAutoConfiguration, NacosServiceRegistryAutoConfiguration 中加载了一个叫 NacosAutoServiceRegistration 的Bean,

这个Bean的父类实现了 ApplicationListener 这个接口,并监听了WebServerInitializedEvent类型的事件,在Tomcat启动后会发布WebServerInitializedEvent的事件,事件被监听到以后,就会调用 NacosServiceRegistryregister 方法向Nacos服务端注册实例,临时实例使用 RPC 调用,永久实例使用 HTTP 调用。

2.服务端处理请求原理图

Processon 地址:https://www.processon.com/diagraming/67301240be9d2e22e50d3a19

Nacos服务注册原理-服务端

注册临时实例:

RequestHandlerRegistry监听了ContextRefreshedEvent事件,在 Springboot 启动时context初始化完成后,通知RequestHandlerRegistry开始注册RequestHandler的全部实现类,这里面就包括InstanceRequestHandler

注册实例的 grpc 请求会被GrpcRequestAcceptor接口, 从RequestHandlerRegistry中拿到InstanceRequestHandler处理实例注册请求,然后调用EphemeralClientOperationServiceImpl.registerInstance() , 发布客户端注册事件ClientRegisterServiceEvent.

注册永久实例:

在Springboot 启动时会加载BeanPersistentClientOperationServiceImpl,初始化CPProtocol, 创建 NacosStateMachine, 并向状态机注册请求处理器EphemeralClientOperationServiceImpl, 启动RaftServer集群。

注册实例的 HTTP 请求进入InstanceControllerregister方法,然后调用EphemeralClientOperationServiceImplderegisterInstance()方法,提交注册请求给 raft 集群,集群会让 Leader 节点处理本次写操作,最终会由状态机注册的processor也就是EphemeralClientOperationServiceImpl处理,调用它的onApply方法,发布客户端注册事件ClientRegisterServiceEvent.

处理客户端注册事件

监听客户端注册事件的ClientServiceIndexesManager收到通知以后,将实例信息保存到本地注册表,并发布ServiceChangedEvent事件通知其他客户端,

NamingSubscriberServiceV2Impl监听到ServiceChangedEvent发布后,创建信息推送任务,添加到延迟任务执行引擎PushDelayTaskExecuteEngine, 引擎执行推送任务。

三、源码分析

客户端

当我们服务引入spring-cloud-starter-alibaba-nacos-discovery,便可以实现自动进行注册,这是因为在spring.facotries中自动装配了NacosServiceRegistryAutoConfiguration

image-20241107130511850

1. NacosServiceRegistryAutoConfiguration加载Bean

image-20241107135455045

此类中定义了三个 Bean:NacosServiceRegistry, NacosRegistration , NacosAutoServiceRegistration

仔细看会发现,前面两个Bean 都是 NacosAutoServiceRegistration 的入参

1.1 NacosServiceRegistry

NacosServiceRegistry 的构造函数入参主要是一些注册需要的配置信息,下面的register 方法就是实现服务注册的,不过要想在服务启动时自动完成注册,还得靠 NacosAutoServiceRegistration

image-20241107144358116

1.2 NacosRegistration
  • registrationCustomizers:一个 NacosRegistrationCustomizer 类型的列表,可能用于自定义注册过程。
  • nacosDiscoveryProperties:包含 Nacos 服务发现的相关配置。
  • contextApplicationContext 类型的对象,表示 Spring 应用上下文,可能用于访问 Spring 框架的功能。

image-20241107151522271

1.3 NacosAutoServiceRegistration

image-20241107155551813

这里我在查看类图的时候,图中并不显示 NacosAutoServiceRegistration ,而是从它的父类开始展示,没找到在哪里可以配置。不过可以按空格添加这个进来,也算是个办法。

从类图中可以看到实现了 ApplicationListener 接口,这是实现自动注册的关键。

image-20241107165110867

2. 监听WEB容器事件

ApplicationListener 是 Spring 框架中一个接口,它属于 org.springframework.context 包。这个接口允许 beans 监听 Spring 事件发布系统发布的事件。

image-20241107165642159

WebServerInitializedEvent 是 Spring Boot 中的一个具体事件类,它属于 org.springframework.boot.web.context 包,继承自ApplicationEvent。这个事件在嵌入式 web 服务器(如 Tomcat、Jetty 或 Undertow)初始化完成后发布。

当你创建一个 ApplicationListener 的实现,并指定 WebServerInitializedEvent 作为泛型参数时,Spring 容器会自动调用你的 onApplicationEvent 方法,并将 WebServerInitializedEvent 的实例作为参数传递给你的 listener。

image-20241107165813117

SmartLifecycle 是一个接口,它继承自 Lifecycle 接口,允许细粒度的控制Bean的生命周期行为。

start方法在Tomcat容器启动后,发布事件 ServletWebServerInitializedEvent, ServletWebServerInitializedEvent 继承自WebServerInitializedEvent

image-20241107171719648

3. 处理容器事件

所以当容器初始化完成后,会调用 org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration#onApplicationEvent

image-20241107174118933

// org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration#start
public void start() {
   
   
  	// 配置:spring.cloud.nacos.discovery.enabled
    if (!this.isEnabled()) {
   
   
        if (logger.isDebugEnabled()) {
   
   
            logger.debug("Discovery Lifecycle disabled. Not starting");
        }

    } else {
   
   
        // 是否已启动
        if (!this.running.get()) {
   
   
          	// 发布预注册事件
            this.context.publishEvent(new InstancePreRegisteredEvent(this, this.getRegistration()));
          	// 开始注册
            this.register();
            if (this.shouldRegisterManagement()) {
   
   
                this.registerManagement();
            }
						// 发布注册后事件
            this.context.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值