乐趣区

关于java:面试官Nacos-为什么这么强讲讲实现原理我懵了

起源:blog.csdn.net/cold___play/article/details/108032204

Nacos 架构

  • Provider APP:服务提供者
  • Consumer APP:服务消费者
  • Name Server:通过 VIP(Virtual IP)或 DNS 的形式实现 Nacos 高可用集群的服务路由
  • Nacos Server:Nacos 服务提供者,外面蕴含的 Open API 是性能拜访入口,Conig Service、Naming Service 是 Nacos 提供的配置服务、命名服务模块。Consitency Protocol 是一致性协定,用来实现 Nacos 集群节点的数据同步,这里应用的是 Raft 算法(Etcd、Redis 哨兵选举)
  • Nacos Console:控制台

注册核心的原理

  • 服务实例在启动时注册到服务注册表,并在敞开时登记
  • 服务消费者查问服务注册表,取得可用实例
  • 服务注册核心须要调用服务实例的健康检查 API 来验证它是否可能解决申请

SpringCloud 实现注册的机会

在 Spring-Cloud-Common 包中有一个类org.springframework.cloud. client.serviceregistry .ServiceRegistry , 它是 Spring Cloud 提供的服务注册的规范。集成到 Spring Cloud 中实现服务注册的组件, 都会实现该接口。

该接口有一个实现类是 NacoServiceRegistry。

SpringCloud 集成 Nacos 的实现过程:

spring-clou-commons 包的 META-INF/spring.factories 中蕴含主动拆卸的配置信息如下:

其中 AutoServiceRegistrationAutoConfiguration 就是服务注册相干的配置类:

AutoServiceRegistrationAutoConfiguration 配置类中, 能够看到注入了一个 AutoServiceRegistration 实例, 该类的关系图如下所示。

能够看出, AbstractAutoServiceRegistration抽象类实现了该接口, 并且最重要的是 NacosAutoServiceRegistration 继承了AbstractAutoServiceRegistration

看到 EventListener 咱们就应该晓得,Nacos 是通过 Spring 的事件机制继承到 SpringCloud 中去的。

AbstractAutoServiceRegistration实现了 onApplicationEvent 形象办法, 并且监听 WebServerInitializedEvent 事件 (当 Webserver 初始化实现之后) , 调用this.bind (event) 办法。

最终会调用 NacosServiceREgistry.register() 办法进行服务注册。

NacosServiceRegistry 的实现

NacosServiceRegistry.registry 办法中, 调用了 Nacos Client SDK 中的 namingService.registerInstance 实现服务的注册。

跟踪 NacosNamingService 的 registerInstance() 办法:

  • 通过 beatReactor.addBeatInfo() 创立心跳信息实现衰弱检测, Nacos Server 必须要确保注册的服务实例是衰弱的, 而心跳检测就是服务衰弱检测的伎俩。
  • serverProxy.registerService()实现服务注册

心跳机制:

从上述代码看, 所谓心跳机制就是客户端通过 schedule 定时向服务端发送一个数据包 , 而后启动 - 个线程一直检测服务端的回应, 如果在设定工夫内没有收到服务端的回应, 则认为服务器呈现了故障。Nacos 服务端会依据客户端的心跳包不断更新服务的状态。

注册原理:

Nacos 提供了 SDK 和 Open API 两种模式来实现服务注册。

Open API:

SDK:

这两种模式实质都一样,底层都是基于 HTTP 协定实现申请的。所以注册服务就是发送一个 HTTP 申请:

对于 nacos 服务端,对外提供的服务接口申请地址为 nacos/v1/ns/instance,实现代码咋nacos-naming 模块下的 InstanceController 类中:

  • 从申请参数汇总取得 serviceName(服务名)和 namespaceId(命名空间 Id)
  • 调用 registerInstance 注册实例

  • 创立一个控服务(在 Nacos 控制台“服务列表”中展现的服务信息),实际上是初始化一个 serviceMap,它是一个 ConcurrentHashMap 汇合
  • getService,从 serviceMap 中依据 namespaceId 和 serviceName 失去一个服务对象
  • 调用 addInstance 增加服务实例

  • 依据 namespaceId、serviceName 从缓存中获取 Service 实例
  • 如果 Service 实例为空,则创立并保留到缓存中

  • 通过 putService() 办法将服务缓存到内存
  • service.init()建设心跳机制
  • consistencyService.listen实现数据一致性监听

service.init ()办法的如下图所示,它次要通过定时工作一直检测以后服务下所有实例最初发送心跳包的工夫。如果超时, 则设置 healthy 为 false 示意服务不衰弱, 并且发送服务变更事件。

在这里请大家思考一一个问题, 服务实例的最初心跳包更新工夫是谁来触发的? 实际上后面有讲到, Nacos 客户端注册服务的同时也建设了心跳机制。

putService 办法,它的性能是将 Service 保留到 serviceMap 中:

持续调用 addInstance 办法把以后注册的服务实例保留到 Service 中:

总结:

  • Nacos 客户端通过 Open API 的模式发送服务注册申请
  • Nacos 服务端收到申请后,做以下三件事:
    • 构建一个 Service 对象保留到 ConcurrentHashMap 汇合中
    • 应用定时工作对以后服务下的所有实例建设心跳检测机制
    • 基于数据一致性协定服务数据进行同步

服务提供者地址查问

Open API:

SDK:

InstanceController 中的 list 办法:

  • 解析申请参数
  • 通过 doSrvIPXT 返回服务列表数据

  • 依据 namespaceId、serviceName 取得 Service 实例
  • 从 Service 实例中基于 srvIPs 失去所有服务提供者实例
  • 遍历组装 JSON 字符串并返回

Nacos 服务地址动静感知原理

能够通过 subscribe 办法来实现监听,其中 serviceName 示意服务名、EventListener 示意监听到的事件:

具体调用形式如下:

或者调用 selectInstance 办法,如果将 subscribe 属性设置为 true,会主动注册监听:

Nacos 客户端中有一个 HostReactor 类,它的性能是实现服务的动静更新,基本原理是:

  • 客户端发动工夫订阅后,在 HostReactor 中有一个 UpdateTask 线程,每 10s 发送一次 Pull 申请,取得服务端最新的地址列表
  • 对于服务端,它和服务提供者的实例之间维持了心跳检测,一旦服务提供者出现异常,则会发送一个 Push 音讯给 Nacos 客户端,也就是服务端消费者
  • 服务消费者收到申请之后,应用 HostReactor 中提供的 processServiceJSON 解析音讯,并更新本地服务地址列表

近期热文举荐:

1.1,000+ 道 Java 面试题及答案整顿(2022 最新版)

2. 劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4. 别再写满屏的爆爆爆炸类了,试试装璜器模式,这才是优雅的形式!!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

退出移动版