首页 > 其他分享 >Nacos学习心得

Nacos学习心得

时间:2024-09-18 18:54:54浏览次数:9  
标签:服务 学习心得 Nacos 实例 集群 注册 健康检查

        最近面试发现现在面试不仅要求会用常用的微服务组件,还需要能说出原理和各种什么功能。遂产生了开始学习《Nacos架构&原理》的念头,以下为学习笔记。

0.Nacos的一些背景介绍

Nacos的前身是阿里的三个产品CongigServer,VIPServer,Diamond。

阿里在18年开源Nacos的初衷是认为自己产品不比别的产品差,缺被迫要兼容不如自己的产品,遂想开源出去,成为默认标准。

以现在24年来看,阿里无疑是成功了的。

1. Nocos的配置管理

1.1 背景

 在单体架构的时候我们可以将配置写在配置文件中,但有 个缺点就是每次修改配置都需要重启服务才能生效。
当应用程序实例比较少的时候还可以维护。如果转向微服务架构有成百上千个实例,每修改一次配置要将全部实例重启,不仅增加了系统的不稳定性,也提高了维护的成本。

1.2 Nacos的配置模型

1. Nacos 提供可视化的控制台,可以对配置进行发布、更新、删除、灰度、版本管理等功能。

2. SDK 可以提供发布配置、更新配置、监听配置等功能。

3. SDK 通过 GRPC 长连接监听配置变更,Server 端对比 Client 端配置的 MD5 和本地 MD5是否相等,不相等推送配置变更。 

4. SDK 会保存配置的快照,当服务端出现问题的时候从本地获取。

1.3Nacos ⼀致性协议

1.3.1为什么 Nacos 需要一致性协议

 Nacos 在开源支持就定下了 个目标,尽可能的减少用户部署以及运维成本,做到用户只需要一个程序包,就可以快速以单机模式启动 Nacos 或者以集群模式启动 Nacos。而 Nacos 是一个需要存储数据的组件,因此,为了实现这个目标,就需要在 Nacos 内部实现数据存储。单机下其实问题不大,简单的内嵌关系型数据库即可;但是集群模式下,就需要考虑如何保障各个节点之间的数据 致性以及数据同步,而要解决这个问题,就不得不引入共识算法,通过算法来保障各个节点之间的数据的一致性。

(ps:这段书中写的不是很好,没有讲清楚为什么Nacos要在内部实现数据存储)

1.3.2为什么 Nacos 选择了 Raft 以及 Distro

这其实要从 Nacos 的场景出发的:Nacos 是一个集服务注册发现以及配置管理于一体的组件,因此对于集群下,各个节点之间的数据一致性保障问题,需要拆分成两个方面
从服务注册发现来看
服务发现注册中心,在当前微服务体系下,是十分重要的组件,服务之间感知对方服务的当前可正常提供服务的实例信息,必须从服务发现注册中心进行获取,因此对于服务注册发现中心组件的可用性,提出了很高的要求,需要在任何场景下,尽最大可能保证服务注册发现能力可以对外提供服务。
Nacos 服务发现注册中的非持久化服务,采取了心跳可自动完成服务数据补偿的机制(即需要客户端上报心跳进行服务实例续约)。如果数据丢失的话,是可以通过该机制快速弥补数据丢失。
因此,为了满足服务发现注册中心的可用性,强一致性的共识算法这里就不太合适了,因为强一致性共识算法能否对外提供服务是有要求的,如果当前集群可用的节点数没有过半的话,整个算法直接“罢工”,而最终一致共识算法的话,更多保障服务的可用性,并且能够保证在一定的时间内各个节点之间的数据能够达成一致。
而对于 Nacos 服务发现注册中的持久化服务,因为所有的数据都是直接使用调用 Nacos服务端直接创建,因此需要由 Nacos 保障数据在各个节点之间的强一致性,故而针对此类型的服务数据,选择了强一致性共识算法来保障数据的一致性。
从配置管理来看
配置数据,是直接在 Nacos 服务端进行创建并进行管理的,必须保证大部分的节点都保存了此配置数据才能认为配置被成功保存了,否则就会丢失配置的变更,如果出现这种情况,问题是很严重的,如果是发布重要配置变更出现了丢失变更动作的情况,那多半就要引起严重的现网故障(直接或者间接影响到用户正常使用产品。)了,因此对于配置数据的管理,是必须要求集群中大部分的节点是强一致的,而这里的话只能使用强一致性共识算法。
为什么是 Raft 和 Distro 呢
对于强一致性共识算法,当前工业生产中,最多使用的就是 Raft 协议,Raft 协议更容易让人理解,并且有很多成熟的工业算法实现,比如蚂蚁金服的 JRaft、Zookeeper 的 ZAB、Consul 的 Raft、百度的 braft、Apache Ratis;因为 Nacos 是 Java 技术栈,因此只能在 JRaft、ZAB、ApacheRatis 中选择,但是 ZAB 因为和 Zookeeper 强绑定,再加上希望可以和 Raft 算法库的支持团队随时沟通交流,因此选择了 JRaft,选择 JRaft 也是因为 JRaft 支持多 RaftGroup,为 Nacos 后面的多数据分片带来了可能。
而 Distro 协议是阿里巴巴自研的一个最终一致性协议,而最终一致性协议有很多,比如 Gossip、Eureka 内的数据同步算法。而 Distro 算法是集 Gossip 以及 Eureka 协议的优点并加以优化而出来的,对于原生的 Gossip,由于随机选取发送消息的节点,也就不可避免的存在消息重复发送给同节点的情况,增加了网络的传输的压力,也给消息节点带来额外的处理负载,而 Distro 算法引入了权威 Server 的概念,每个节点负责一部分数据以及将自己的数据同步给其他节点,有效的降低了消息冗余的问题。

1.3.3 配置⼀致性模型

Nacos 配置管理一致性协议分为两个大部分,一部分是 Server 间一致性协议,另一部分是 SDK 与Server 的一致性协议,配置作为分布式系统中非强一致数据,在出现脑裂的时候可用性高于一致性,因此阿里配置中心是采用 AP一致性协议。

1.3.3.1 Server 间的一致性协议

有 DB 模式(读写分离架构)

一致性的核心是 Server 与 DB 保持数据一致性,从而保证 Server 数据一致;Server 之间都是对等的。数据写任何一个 Server,优先持久化,持久化成功后异步通知其他节点到数据库中拉取最新配置值,并且通知写入成功。

无 DB 模式
Server 间采用 Raft 协议保证数据一致性。Nacos提供此模式,是方便用户本机运行,降低对存储依赖。

1.3.3.2 SDK 与 Server 的 致性协议

SDK 与 Server 致性协议的核心是通过判断 MD5 值是否一致,如果不一致就拉取最新值。

Nacos 1.X 采用 Http 1.1 短链接模拟长链接,每 30s 发 个心跳跟 Server 对比 SDK 配置 MD5 值是否跟 Server 保持 致,如果 致就 hold 住链接,如果有不 致配置,就把不 致的配置返回,然后 SDK 获取最新配置值。

Nacos 2.x 相比上面 30s 次的长轮训,升级成长链接模式,配置变更,启动建立长链接,配置变更服务端推送变更配置列表,然后 SDK 拉取配置更新,因此通信效率大幅提升。

1.4 使用

1.4.1 Nacos控制台的一些参数

命名空间(Namespace)
用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之 是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如数据库配置、限流阈值、降级开关)隔离等。如果在没有指定 Namespace 的情况下,默认使用 public 命名空间。

配置 ID(Data ID)
Nacos 中的某个配置集的 ID。配置集 ID是划分配置的维度之一 。Data ID 通常用于划分系统的配置集。 一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。Data ID尽量保障全局唯一。

配置组(Group)
Nacos 中的 组配置集,是配置的维度之一。通过一个有意义的字符串(如 ABTest 中的实验组、对照组)对配置集进行分组,从而区分 Data ID 相同的配置集。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT GROUP 。配置分组的常见场景:不同的应用或组件使用了相同的配置项,如 database url 配置和 MQ Topic 配置。

1.4.2 共享配置

1.在Nacos控制台 配置管理->配置列表中点击+新建一个配置:

填写模块通用的配置

2.引入依赖

  <!--nacos配置管理-->
  <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
  </dependency>
  <!--读取bootstrap文件-->
  <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-bootstrap</artifactId>
  </dependency>

 3.在resources目录新建一个bootstrap.yaml文件

spring:
  application:
    name: user-service # 服务名称
  profiles:
    active: dev
  cloud:
    nacos:
      server-addr: 127.0.0.1 # nacos地址
      config:
        file-extension: yaml # 文件后缀名
        shared-configs: # 共享配置
          - dataId: comm.yaml # 共享mybatis配置,nacos控制台填写的名称

之后将application.yaml中 重复的配置项删除。

2. Nacos的服务发现

2.1 Nacos 注册中心的设计原理

2.1.1 数据模型

注册中心的核心数据是服务的名字和它对应的网络地址,当服务注册了多个实例时,我们需要对不健康的实例进行过滤或者针对实例的 些特征进行流量的分配,那么就需要在实例上存储 些例如健康状态、权重等属性。随着服务规模的扩大,渐渐的又需要在整个服务级别设定 些权限规则、以及对所有实例都生效的 些开关,于是在服务级别又会设立 些属性。再往后,我们又发现单个服务的实例又会有划分为多个子集的需求,例如 个服务是多机房部署的,那么可能需要对每个机房的实例做不同的配置,这样又需要在服务和实例之间再设定 个数据级别。在Nacos 在经过内部多年生产经验后提炼出的数据模型,则是一种服务 集群 实例的三层模型。

数据隔离级别

Nacos 提供了四层的数据逻辑隔离模型,用户账号(Company)对应的可能是一个企业或者独立的个体,这个数据一般情况下不会透传到服务注册中心。一个用户账号可以新建多个命名空间(Namespace),每个命名空间对应一个客户端实例,这个命名空间对应的注册中心物理集群是可以根据规则进行路由的,这样可以让注册中心内部的升级和迁移对用户是无感知的,同时可以根据用户的级别,为用户提供不同服务级别的物理集群。再往下是服务分组(Group)和服务名(Service)组成的二维服务标识,可以满足接口级别的服务隔离。

临时实例和持久化实例

在定义上区分临时实例和持久化实例的关键是健康检查的方式。临时实例使用客户端上报模式,而持久化实例使用服务端反向探测模式。临时实例需要能够自动摘除不健康实例,而且无需持久化存储实例,那么这种实例就适用于类 Gossip 的协议。持久化实例使用服务端探测的健康检查方式,因为客户端不会上报心跳,那么自然就不能去自动摘除下线的实例。

一些基础的组件例如数据库、缓存等,这些往往不能上报心跳,这种类型的服务在注册时,就需要作为持久化实例注册。而上层的业务服务,例如微服务或者 Dubbo 服务,服务的 Provider 端支持添加汇报心跳的逻辑,此时就可以使用动态服务的注册方式。

在 Nacos2.0 中是否持久化的数据抽象至服务级别,且不再允许 个服务同时存在持久化实例和非持久化实例,实例的持久化属性继承自服务的持久化属性。

2.1.2 数据一致性

 一个是基于简化的 Raft 的 CP 一致性,一个是基于自研协议 Distro 的AP 一致性。Raft 协议不必言,基于 Leader 进行写入,其 CP 也并不是严格的,只是能保证一半所见一致,以及数据的丢失概率较小。Distro 协议则是参考了内部 ConfigServer 和开源 Eureka,在不借助第三方存储的情况下,实现基本大同小异。Distro 重点是做了 些逻辑的优化和性能的调优。

ps:CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。

2.1.3 负载均衡

负载均衡严格的来说,并不算是传统注册中心的功能。一般来说服务发现的完整流程应该是先从注册中心获取到服务的实例列表,然后再根据自身的需求,来选择其中的部分实例或者按照一定的流量分配机制来访问不同的服务提供者,因此注册中心本身一般不限定服务消费者的访问策略。

服务端的负载均衡,给服务提供者更强的流量控制权,但是无法满足不同的消费者希望使用不同负载均衡策略的需求。而不同负载均衡策略的场景,确实是存在的。而客户端的负载均衡则提供了这种灵活性,并对用户扩展提供更加友好的支持。但是客户端负载均衡策略如果配置不当,可能会导致服务提供者出现热点,或者压根就拿不到任何服务提供者。

在 Nacos 0.7.0 版本中,除了提供基于健康检查和权重的负载均衡方式外,还新提供了基于第三方 CMDB 的标签负载均衡器,使用基于标签的负载均衡器,目前可以实现同标签优先访问的流量调度策略。实际的应用场景中,可以用来实现服务的就近访问,当服务部署在多个地域时,这非常有用。

Nacos 试图做的是将服务端负载均衡与客户端负载均衡通过某种机制结合起来,提供用户扩展性,并给予用户充分的自主选择权和轻便的使用方式。

2.1.4 健康检查

Nacos 目前支持临时实例使用心跳上报方式维持活性,发送心跳的周期默认是 5 秒,Nacos 服务端会在 15 秒没收到心跳后将实例设置为不健康,在 30 秒没收到心跳时将这个临时实例摘除。

有 些服务无法上报心跳,但是可以提供 个检测接口,由外部去探测。服务端健康检查最常见的方式是 TCP 端口探测和 HTTP 接口返回码探测,这两种探测方式因为其协议的通用性可以支持绝大多数的健康检查场景。

客户端健康检查和服务端健康检查有一些不同的关注点。客户端健康检查主要关注客户端上报心跳的方式、服务端摘除不健康客户端的机制。而服务端健康检查,则关注探测客户端的方式、灵敏度及设置客户端健康状态的机制。从实现复杂性来说,服务端探测肯定是要更加复杂的,因为需要服务端根据注册服务配置的健康检查方式,去执行相应的接口,判断相应的返回结果,并做好重试机制和线程池的管理。这与客户端探测,只需要等待心跳,然后刷新 TTL 是不 样的。同时服务端健康检查无法摘除不健康实例,这意味着只要注册过的服务实例,如果不调用接口主动注销,这些服务实例都需要去维持健康检查的探测任务,而客户端则可以随时摘除不健康实例,减轻服务端的压力。

Nacos 既支持客户端的健康检查,也支持服务端的健康检查,同一个服务可以切换健康检查模式。这种健康检查方式的多样性非常重要,这样可以支持各种类型的服务,让这些服务都可以使用到 Nacos 的负载均衡能力。

2.1.5 性能与容量

Zookeeper 的容量,从存储节点数来说,可以达到百万级别。不过这并不代表容量的全部,当大量的实例上下线时,Zookeeper 的表现并不稳定,同时在推送机制上的缺陷,会引起客户端的资源占用上升,从而性能急剧下降,其次 Zookeeper 舍弃了服务发现的基本功能如健康检查、友好的查询接口,它在支持这些功能的时候,显然需要增加这些逻辑,甚至弃用现有的数据结构;最后,Paxos 协议本身就限制了 Zookeeper 集群的规模,3、5 个节点是不能应对大规模的服务订阅和查询的。

Eureka 在服务实例规模在 5000 左右的时候,就已经出现服务不可用的问题,甚至在压测的过程中,如果并发的线程数过高,就会造成 Eureka crash。不过如果服务规模在 1000 上下,几乎目前所有的注册中心都可以满足。

Nacos 在开源版本中,服务实例注册的支撑量约为 100 万,服务的数量可以达到 10 万以上。

2.1.6 集群扩展性

集群扩展性和集群容量以及读写性能关系紧密,集群扩展性的另一个方面是多地域部署和容灾的支持。当讲究集群的高可用和稳定性以及网络上的跨地域延迟要求能够在每个地域都部署集群的时候,我们现有的方案有多机房容灾异地多活多数据中心等。

双机房容灾

Nacos 支持两种模式的部署,一种是和 Eureka 样的 AP 协议的部署,这种模式只支持临时实例,可以完美替代当前的 Zookeeper、Eureka,并支持机房容灾。另一种是支持持久化实例的 CP 模式,这种情况下不支持双机房容灾。

异地多活

很多业务组件的异地多活正是依靠服务注册中心和配置中心来实现的,这其中包含流量的调度和集群的访问规则的修改等。机房容灾是异地多活的一部分,但是要让业务能够在访问服务注册中心时,动态调整访问的集群节点,这需要第三方的组件来做路由。

多数据中心

多数据中心其实也算是异地多活的一部分。Nacos 基于阿里巴巴内部的使用经验,提供的解决方案是采用 Nacos-Sync 组件来做数据中心之间的数据同步,这意味着每个数据中心的 Nacos 集群都会有多个数据中心的全量数据。

2.2 Nacos 注册中心服务数据模型

2.2.1 服务(Service)和服务实例(Instance)

在服务发现领域中,服务指的是由应用程序提供的一个或一组软件功能的一种抽象概念。它和应用有所不同,应用的范围更广,和服务属于包含关系,即一个应用可能会提供多个服务。为了能够更细粒度地区分和控制服务,Nacos 选择服务作为注册中心的最基本概念。

而服务实例(以下简称实例)是某个服务的具体提供能力的节点,一个实例仅从属于一个服务,而一个服务可以包含一个或多个实例。在许多场景下,实例又被称为服务提供者(Provider),而使用该服务的实例被称为服务消费者(Consumer)。

定义服务

在 Nacos 中,服务的定义包括以下几个内容:
 命名空间(Namespace):Nacos 数据模型中最顶层、也是包含范围最广的概念,用于在类似环境或租户等需要强制隔离的场景中定义。Nacos 的服务也需要使用命名空间来进行隔离。
 分组(Group):Nacos 数据模型中次于命名空间的 种隔离概念,区别于命名空间的强制隔离属性,分组属于一种弱隔离概念,主要用于逻辑区分一些服务使用场景或不同应用的同名服务,最常用的情况主要是同一个服务的测试分组和生产分组、或者将应用名作为分组以防止不同应用提供的服务重名。
 服务名(Name):该服务实际的名字,一般用于描述该服务提供了某种功能或能力。

之所以 Nacos 将服务的定义拆分为命名空间、分组和服务名,除了方便隔离使用场景外,还有方便用户发现唯一服务的优点。在注册中心的实际使用场景上,同一个公司的不同开发者可能会开发出类似作用的服务,如果仅仅使用服务名来做服务的定义和表示,容易在一些通用服务上出现冲突,比如登陆服务等。

通常推荐使用由运行环境作为命名空间、应用名作为分组和服务功能作为服务名的组合来确保该服务的天然唯一性,当然使用者可以忽略命名空间和分组,仅使用服务名作为服务唯一标示,这就需要使用者在定义服务名时额外增加自己的规则来确保在使用中能够唯一定位到该服务而不会发现到错误的服务上。

服务元数据
服务的定义只是为服务设置了一些基本的信息,用于描述服务以及方便快速的找到服务,而服务的元数据是进一步定义了 Nacos 中服务的细节属性和描述信息。主要包含:
 健康保护阈值(ProtectThreshold):为了防止因过多实例故障,导致所有流量全部流入剩余实例,继而造成流量压力将剩余实例被压垮形成的雪崩效应。应将健康保护阈值定义为 个 0 到 1之间的浮点数。当域名健康实例数占总服务实例数的比例小于该值时,无论实例是否健康,都会将这个实例返回给客户端。这样做虽然损失了一部分流量,但是保证了集群中剩余健康实例能正常工作。
 实例选择器(Selector):用于在获取服务下的实例列表时,过滤和筛选实例。该选择器也被称为路由器,目前 Nacos 支持通过将实例的部分信息存储在外部元数据管理 CMDB 中,并在发现服务时使用 CMDB 中存储的元数据标签来进行筛选的能力。
 拓展数据(extendData):用于用户在注册实例时自定义扩展的元数据内容,形式为 K-V 。可以在服务中拓展服务的元数据信息,方便用户实现自己的自定义逻辑。

定义实例
由于服务实例是具体提供服务的节点,因此 Nacos 在设计实例的定义时,主要需要存储该实例的些网络相关的基础信息,主要包含以下内容:
 网络 P 地址:该实例的 P 地址,在 Nacos2.0 版本后支持设置为域名。、

 网络端口:该实例的端口信息。
 健康状态(Healthy):用于表示该实例是否为健康状态,会在 Nacos 中通过健康检查的手段进行维护。
 集群(Cluster):用于标示该实例归属于哪个逻辑集群。
 拓展数据(extendData):用于用户自定义扩展的元数据内容,形式为 K-V。可以在实例中拓展该实例的元数据信息,方便用户实现自己的自定义逻辑和标示该实例。

实例元数据
和服务元数据不同,实例的元数据主要作用于实例运维相关的数据信息。主要包含:
 权重(Weight):实例级别的配置。权重为浮点数,范围为 0-10000。权重越大,分配给该实例的流量越大。
 上线状态(Enabled):标记该实例是否接受流量,优先级大于权重和健康状态。用于运维人员在不变动实例本身的情况下,快速地手动将某个实例从服务中移除。
 拓展数据(extendData):不同于实例定义中的拓展数据,这个拓展数据是给予运维人员在不变动实例本身的情况下,快速地修改和新增实例的扩展数据,从而达到运维实例的作用。

在 Nacos2.0 版本中,实例数据被拆分为实例定义和实例元数据,主要是因为这两类数据其实是同一个实例的两种不同场景:开发运行场景及运维场景。

持久化属性

Nacos 提供两种类型的服务:持久化服务和非持久化服务,分别给类 DNS 的基础的服务组件场景和上层实际业务服务场景使用。

在 Nacos2.0 版本后,持久化属性的定义被抽象到服务中,一个服务只能被定义成持久化服务或非持久化服务, 旦定义完成,在服务生命周期结束之前,无法更改其持久化属性。
持久化属性将会影响服务及实例的数据是否会被 Nacos 进行持久化存储,设置为持久化之后,实例将不会再被自动移除,需要使用者手动移除实例。

2.2.2 集群(Cluster)

集群是 Nacos 中一组服务实例的一个逻辑抽象的概念,它介于服务和实例之间,是一部分服务属性的下沉和实例属性的抽象。

定义集群

在 Nacos 中,集群中主要保存了有关健康检查的一些信息和数据:
 健康检查类型(HealthCheckType):使用哪种类型的健康检查方式,目前支持:TCP,HTTP,MySQL;设置为 NONE 可以关闭健康检查。
 健康检查端口(HealthCheckPort):设置用于健康检查的端口。
 是否使用实例端口进行健康检查(Use nstancePort):如果使用实例端口进行健康检查,将会使用实例定义中的网络端口进行健康检查,而不再使用上述设置的健康检查端口进行。
 拓展数据(extendData):用于用户自定义扩展的元数据内容,形式为 K V 。可以自定义扩展该集群的元数据信息,方便用户实现自己的自定义逻辑和标示该集群。

2.2.3 生命周期

在注册中心中,实例数据都和服务实例的状态绑定,因此服务实例的状态直接决定了注册中心中实例数据的生命周期。而服务作为实例的聚合抽象,生命周期也会由服务实例的状态来决定。

服务的⽣命周期
服务的生命周期相对比较简单,是从用户向注册中心发起服务注册的请求开始。在 Nacos 中,发起服务注册有两种方式,一种是直接创建服务,一种是注册实例时自动创建服务;前者可以让发起者在创建时期就制定一部分服务的元数据信息,而后者只会使用默认的元数据创建服务。
在生命周期期间,用户可以向服务中新增,删除服务实例,同时也能够对服务的元数据进行修改。
当用户主动发起删除服务的请求或一定时间内服务下没有实例(无论健康与否)后,服务才结束其生命周期,等待下一次的创建。

实例的⽣命周期
实例的生命周期开始于注册实例的请求。但是根据不同的持久化属性,实例后续的生命周期有一定的不同。
持久化的实例,会通过健康检查的状态维护健康状态,但是不会自动的终止该实例的生命周期;在生命周期结束之前,持久化实例均可以被修改数据,甚至主动修改其健康状态。唯一终止持久化实例生命周期的方式就是注销实例的请求。
而非持久化的实例,会根据版本的不同,采用不同的方式维持健康状态:如果是 Nacos1.0 的版本,会通过定时的心跳请求来进行续约,当超过一定时间内没有心跳进行续约时,该非持久化实例则终止生命周期;如果是 Nacos2.0 的版本,会通过 gRPC 的长连接来维持状态,当连接发生中断时,该非持久化实例则终止生命周期。当然,非持久化实例也可以通过注销实例的请求,主动终止其生命周期,但是由于长连接和心跳续约的存在,可能导致前一个实例数据的生命周期刚被终止移除,立刻又因为心跳和长连接的补偿请求,再次开启实例的生命周期,给人一种注销失败的假象。

集群的⽣命周期
集群的生命周期则相对复杂,由于集群作为服务和实例的一个中间层,因此集群的生命周期与实例和服务的生命周期均有关。
集群的生命周期开始与该集群第一个实例的生命周期同时开始,因为一个实例必定归属于一个集群,哪怕是默认的集群,因此当第一个实例的生命周期开始时,也就是集群生命周期的开始;
当一个集群下不存在实例时,集群的生命周期也不会立刻结束,而是会等到这个服务的生命周期结束时,才会一起结束生命周期。

元数据的⽣命周期
由于元数据的其对应的数据模型是紧密关联的,所以元数据的生命周期基本和对应的数据模型保持一致。但是也如前文所说,元数据通常为运维人员的主动操作的数据,会被 Nacos 进行一段时间
内的记忆,因此元数据的生命周期的终止相比对应的数据要滞后;若这滞后期间内,对应的数据又重新开始生命周期,则该元数据的生命周期将被立刻重置,不再终止。

2.3 Nacos 健康检查机制

2.3.1 注册中心的健康检查机制

我们想知道一个服务是否还健康有两种方式。第一种方式是客户端主动上报,告诉服务端自己健康状态,如果在一段时间没有上报,那么我们就认为服务已经不健康。第二种,则是服务端主动向客户端进行探测,检查客户端是否还被能探测到。

在当前主流的注册中心,对于健康检查机制主要都采用了 TTL(Time To Live)机制,即客户端在一定时间没有向注册中心发送心跳,那么注册中心会认为此服务不健康,进而触发后续的剔除逻辑。对于主动探测的方式那么根据不同的场景,需要采用的方式可能会有不同。

2.3.2 Nacos 健康检查机制

临时实例只是临时存在于注册中心中,会在服务下线或不可用时被注册中心剔除,临时实例会与注册中心保持心跳,注册中心会在一段时间没有收到来自客户端的心跳后会将实例设置为不健康,然后在一段时间后进行剔除。
永久实例在被删除之前会永久的存在于注册中心,且有可能并不知道注册中心存在,不会主动向注册中心上报心跳,那么这个时候就需要注册中心主动进行探活。

2.3.2.1 临时实例健康检查机制

在 Nacos 中,用户可以通过两种方式进行临时实例的注册,通过 Nacos 的 OpenAPI 进行服务注册或通过 Nacos 提供的 SDK 进行服务注册。
OpenAPI 的注册方式实际是用户根据自身需求调用 Http 接口对服务进行注册,然后通过 Http 接口发送心跳到注册中心。在注册服务的同时会注册一个全局的客户端心跳检测的任务。在服务一段时间没有收到来自客户端的心跳后,该任务会将其标记为不健康,如果在间隔的时间内还未收到心跳,那么该任务会将其剔除。

ps:通过nacos控制台直接对服务操作是 OpenAPI 进行服务注册方式的一种。


SDK 的注册方式实际是通过 RPC 与注册中心保持连接(Nacos 2.x 版本中,旧版的还是仍然通过OpenAPI 的方式),客户端会定时的通过 RPC 连接向 Nacos 注册中心发送心跳,保持连接的存活。如果客户端和注册中心的连接断开,那么注册中心会主动剔除该 client 所注册的服务,达到下线的效果。同时 Nacos 注册中心还会在注册中心启动时,注册一个过期客户端清除的定时任务,用于删除那些健康状态超过一段时间的客户端。

ps:在系统的pom文件中引入nacos的依赖,配置好配置文件。启动类启动后会在nacos中自动注册一个服务 是SDK注册方式。

2.3.2.2 永久实例健康检查机制

Nacos 中使用 SDK 对于永久实例的注册实际也是使用 OpenAPI 的方式进行注册,这样可以保证
即使是客户端下线后也不会影响永久实例的健康检查。

对于永久实例的的监看检查,Nacos 采用的是注册中心探测机制,注册中心会在永久服务初始化时根据客户端选择的协议类型注册探活的定时任务。Nacos 现在内置提供了三种探测的协议,即Http、TCP 以及 MySQL 。一般而言 Http 和 TCP 已经可以涵盖绝大多数的健康检查场景。MySQL 主要用于特殊的业务场景,例如数据库的主备需要通过服务名对外提供访问,需要确定当前访问数据库是否为主库时,那么我们此时的健康检查接口,是一个检查数据库是否为主库的 MySQL命令。

2.3.2.3集群模式下的健康检查机制

对于集群下的服务,Nacos 一个服务只会被 Nacos 集群中的一个注册中心所负责,其余节点的服务信息只是集群副本,用于订阅者在查询服务列表时,始终可以获取到全部的服务列表。临时实例只会对其被负责的注册中心节点发送心跳信息,注册中心服务节点会对其负责的永久实例进行健康探测,在获取到健康状态后由当前负责的注册中心节点将健康信息同步到集群中的其他的注册中心。

在 Nacos 中,服务的注册从注册方式维度实际可以分为两大类。第一类通过 SDK RPC 连接进行注册,客户端会和注册中心保持链接。第二类,通过 OpenAPI 进行 IP 和端口注册。

对于第一类,只需要和注册中心集群中的任意一台节点建立联系,那么由这个节点负责这个客户端就可以了。注册中心会在启动时注册一个全局的同步任务,用于将其当前负责的所有节点信息同步到集群中的其他节点,其他非负责的节点也会创建该客户端的信息,在非负责的节点上,连接类型的客户端,会有一个续约时间的概念,在收到其他节点的同步信息时,更新续约时间为当前时间,如果在集群中的其他节点在一段时间内没有收到不是自己的负责的节点的同步信息,那么认为此节点已经不健康,从而达到对不是自己负责的节点健康状态检查。

对于第二类方式其实也基本和第一类一致,永久实例会在被主动删除前一直存在于注册中心,所以我们只需要在负责的节点永久实例健康状态变更的时候通知到其余的节点即可。

ps:负责的节点挂了,还怎么进行健康检查

2.4 使用

1、修改 pom.xml,添加 spring-cloud-starter-alibaba-nacos-discovery 依赖:

<dependency>
       <groupId>com.alibaba.cloud</groupId>
       <artifactId>spring-cloud-alibaba-dependencies</artifactId>
       <version>{相应的版本}/version>
       <type>pom</type>
       <scope>import</scope>
</dependency>

2.application.properties 中添加 nacos server 的地址:

spring.cloud.nacos.discovery.server addr=127.0.0.1:8848

3.启动启动类

服务即注册完成。

 参考:Nacos架构&原理免费下载_在线阅读_藏经阁-阿里云开发者社区 (aliyun.com)

标签:服务,学习心得,Nacos,实例,集群,注册,健康检查
From: https://blog.csdn.net/qq_42592739/article/details/142286826

相关文章

  • nacos集群搭建
    一、下载nacos.zip二、配置nacos1.cluster.conf增加配置增加配置2.application.properties增加配置增加配置3.start.cmd增加配置增加jvm配置![](https://img2024.cnblogs.com/blog/3440595/202409/3440595-20240918144826138-1648441835.png)三、启动nacos集群......
  • nacos单机配置集群可能存在的问题
    在一台机器上面搭建nacos-server-2.2.3集群,启动集群抛“Failedtobindtoaddress0.0.0.0/0.0.0.0:9848,java.net.BindException:Addressalreadyinuse:bind”错误。原因分析Nacos默认端口是8848,2.0版本后另外还占用9848,9849两个端口,这两个是gRPC端口,用于服务......
  • springCloud整合nacos
    关于springCloud整合nacos主要步骤如下(主要介绍nacos作为注册中心使用的配置)1、添加依赖;2、添加配置;3、服务启动,查看注册信息1、添加依赖:<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-......
  • Nacos服务治理
    NacosDiscovery服务治理3.1服务治理介绍先来思考一个问题通过上一章的操作,我们已经可以实现微服务之间的调用。但是我们把服务提供者的网络地址(ip,端口)等硬编码到了代码中,这种做法存在许多问题:一旦服务提供者地址变化,就需要手工修改代码一旦是多个服务提供者,无法实......
  • Nacos与Eureka的区别:深入解析微服务中的服务注册与发现
    在微服务架构中,服务注册与发现是确保各个服务之间高效通信与协调的重要机制。随着云原生应用的快速发展,服务治理的需求也在不断增长。在这一背景下,Nacos和Eureka作为两种主流的服务注册与发现工具,各具特色和优势。本文将深入分析Nacos与Eureka之间的区别,帮助开发者选择最适合自......
  • Nacos下载和启动
    Nacos是什么?一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台下载https://github.com/alibaba/nacos/releases/tag/2.1.1启动将下载好的Nacos解压缩,然后到bin目录下打开cmd输入指令:startup.cmd-mstandalone出现下图,表示启动成功:访问Nacos输......
  • nacos2.4.2开启鉴权
    2.2.2版本之前的Nacos默认控制台,无论服务端是否开启鉴权,都会存在一个登录页;这导致很多用户被误导认为Nacos默认是存在鉴权的。在社区安全工程师的建议下,Nacos自2.2.2版本开始,在未开启鉴权时,默认控制台将不需要登录即可访问,同时在控制台中给予提示,提醒用户当前集群未开启鉴权。mac......
  • 【Nacos】下载和启动
    官网说明文档地址:https://nacos.io/docs/latest/quickstart/quick-start/Nacos是“易于构建的云原生平台、配置管理和服务管理平台”。这句话,依据我的理解就是:有部署一个分布式环境很复杂,自己搭建框架对技术和能力要求高。所以,站在巨人肩膀上,你只要知道:如何下载、启动、配置、部......
  • Springboot + nacos + k8s 优雅停机
    需要处理的问题至少有一个服务可用K8S配置滚动部署策略服务下线后不再被调度服务关闭时主动下线nacos服务关闭时清理应用里的loadbalance实例列表缓存之前进来的请求可以返回延迟下线,最大可能保证功能结束业务服务配置nacos优雅停机优雅停机配置与最大等待......
  • nacos未授权访问漏洞,导致被网警找
    背景只做简短汇总,记录一下公司收购了另一家公司,所以相应的后端服务和服务器都交给我管理,但是没有任何的交接文档,大概看了一下代码,依赖的东西就去忙别的了。直到今天网警突然打电话给我说系统有漏洞(CVE-2021-29441),并且给出了访问地址好家伙,直接能看到用户名和密码,岂不是暴力破......