本文详尽的展开介绍 Nacos 注册中心中的服务数据模型内容。

详细介绍Nacos2.0 版本中注册中心所涉及到的数据模型、各个数据模型的含义及各个数据模型的生命周期,

并介绍 Nacos2.0 版本和 Nacos1.0 版本中,服务数据模型的差异点

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

使用支付宝进行付款的时候,或许会要求你先登陆,验证你的身份信息,最后才能进行支付。而这其中,可能涉及到了支付服务,登陆服务,信息验证服务等。都离不开服务的发现。

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

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

2 定义服务

Nacos 中服务的定义包括:

2.1 命名空间(Namespace)

public class Namespace {
     
     private String namespace;
     
     private String namespaceShowName;
     
     private String namespaceDesc;
     
     private int quota;
     
     private int configCount;
   
     private int type;
 }

Nacos 数据模型中最顶层、包含范围最广的概念,用在类似环境或租户等需强制隔离的场景。

Nacos 的服务也需使用命名空间来隔离。

2.2 分组(Group)

Nacos 数据模型中次于命名空间的隔离概念,区别于命名空间的强制隔离属性,分组属于⼀个弱隔离,用于逻辑区分⼀些服务使用场景或不同应用的同名服务。

最常用的情况主要是同⼀个服务的测试分组和生产分组、或将应用名作为分组,以防不同应用提供的服务重名。

2.3 服务名(Name)

该服务实际的名字,⼀般用于描述该服务提供了某种功能或能力。

3 将服务的定义拆分的意义

  • 方便隔离使用场景
  • 方便用户发现唯⼀服务

在注册中心的实际使用场景,同个公司的不同开发者可能开发类似作用的服务,如仅仅使用服务名做服务的定义和表示,容易在⼀些通用服务上出现冲突,

比如登陆服务等。

Nacos注册中心服务数据模型详解_元数据

4 最佳实践

  • 运行环境dev/test/pre/prod作命名空间
  • 应用名gateway作分组
  • 服务功能作为服务名

来确保该服务的天然唯⼀性,可忽略命名空间和分组,仅使用服务名作为服务唯⼀标示,这需使用者在定义服务名时额外增加自己的规则确保在使用中能够唯⼀定位到该服务而不会发现到错误的服务。

5 服务元数据

服务的定义只是为服务设置基本信息,用于描述服务以及方便快速找到服务,而服务元数据是进⼀步定义 Nacos 中服务的细节属性和描述信息。包含:

健康保护阈值(ProtectThreshold)

为防止因过多实例故障,导致所有流量全部流入剩余实例,继而造成流量压力将剩余实例被压垮形成的雪崩效应。应将健康保护阈值定义为⼀个 0 到 1之间的浮点数。当域名健康实例数占总服务实例数的比例小于该值时,无论实例是否健康,都会将这个实例返回给客户端。这样做虽然损失了⼀部分流量,但是保证了集群中剩余健康实例能正常工作。

实例选择器(Selector)

在获取服务下的实例列表时,过滤和筛选实例。该选择器也被称为路由器,目前 Nacos 支持通过将实例的部分信息存储在外部元数据管理 CMDB 中,并在发现服务时使用 CMDB 中存储的元数据标签来进行筛选的能力。

拓展数据(extendData)

用户在注册实例时自定义扩展的元数据内容,形式为 K-V 。可在服务中拓展服务的元数据信息,方便用户实现自己的自定义逻辑。

6 定义实例

服务实例是具体提供服务的节点,因此 Nacos 设计实例的定义时,主要需要存储该实例的⼀些网络相关的基础信息,主要包含以下内容:

  • 网络 IP 地址:该实例的 IP 地址,Nacos2.0 版本后支持设置域名
  • 网络端口:该实例的端口信息
  • 健康状态(Healthy):用于表示该实例是否为健康状态,会在 Nacos 中通过健康检查的手段进行维护,具体内容将在 Nacos 健康检查机制章节中详细说明,读者目前只需要该内容的含义即可
  • 集群(Cluster):标示该实例归属于哪个逻辑集群
  • 拓展数据(extendData):用户自定义扩展的元数据内容KV。可在实例中拓展该实例的元数据信息,方便用户实现自己的自定义逻辑和标示该实例

实例元数据

不同服务元数据,实例元数据主要作用于实例运维相关的数据信息。包含:

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

实例本身情况下,快速地修改和新增实例的扩展数据,达到运维实例。

在 Nacos2.0,实例数据被拆分为实例定义和实例元数据,因为这两类数据其实是同⼀个实例的两种不同场景:

  • 开发运行场景
  • 运维场景

对于上下线及权重这种属性,⼀般认为在实例已经在运行时,需要运维人员手动修改和维护的数据,而 IP,端口和集群等信息,⼀般情况下在实例启动并注册后,则不会在进行变更。将这两部分数据合并后,就能够得到实例的完整信息,也

是 Nacos1.0 版本中的实例数据结构。

同时在 Nacos2.0 版本中,定义实例的这部分数据,会受到持久化属性影响,而实例元数据部分⼀定持久化;因为运维操作需保证操作的原子性,不能因为外部环境的影响而导致操作被重置,例如在 Nacos1.0 版本中,运维人员因为实例所处的网络存在问题,操作⼀个实例下线以此摘除流量,但是同样因为网络问题,该实例与 Nacos 的通信也收到影响,导致实例注销后重新注册,这可能导致上线状态被重新注册而覆盖,失去了运维人员操作的优先级。

这部分元数据也不应无限制存储,如实例确已移除,元数据也应移除。Nacos 2.0 后,通过该接口更新的元数据会在对应实例删除后,依旧存在⼀段时间,如此期间实例重新注册,该元数据依旧生效;可通过如下参数修改记忆时间:

  • nacos.naming.clean.expired-metadata.expired-time
  • nacos.naming.clean.expired-metadata.interval

Nacos注册中心服务数据模型详解_生命周期_02

7 持久化属性

Nacos 提供两种类型的服务:

  • 持久化服务
  • 非持久化服务

分别给:

  • 类 DNS 的基础的服务组件场景
  • 上层实际业务服务场景

使用。为标示该服务是哪种类型的服务,需在创建服务时选择服务的持久化属性。目前大多使用动态服务发现的场景

为非持久化服务的类型(如 Spring Cloud,Dubbo,Service Mesh),Nacos 默认值非持久化服务。

Nacos2.0后,持久化属性的定义被抽象到服务中,⼀个服务只能被定义成持久化服务或非持久化服务,定义完成,在服务生命周期结束前,无法更改其持久化属性。

持久化属性影响服务及实例的数据是否会被 Nacos 持久化存储,设置持久化后,实例将不会再被自动移除,需手动移除实例。

8 集群(Cluster)

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

定义集群

Nacos 中,集群主要保存健康检查的⼀些信息:

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

服务&集群&实例:

Nacos注册中心服务数据模型详解_元数据_03

9 生命周期

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

9.1 服务的⽣命周期

服务的生命周期相对比较简单,是从用户向注册中心发起服务注册的请求开始。

发起服务注册的方式

  • 直接创建服务
    可让发起者在创建时期,就指定⼀部分服务的元数据信息
  • 注册实例时自动创建服务
    仅使用默认的元数据创建服务

生命周期期间,用户可向服务:

  • 新增、删除服务实例
  • 修改服务的元数据

当用户主动发起删除服务的请求或⼀定时间内服务下没有实例(无论健康与否)后,服务才结束其生命周期,等下⼀次创建。

9.2 实例的⽣命周期

开始于注册实例的请求。根据不同持久化属性,实例后续生命周期有不同。

持久化的实例

会通过健康检查的状态维护健康状态,但是不会自动的终止该实例的生命周期;在

生命周期结束之前,持久化实例均可以被修改数据,甚至主动修改其健康状态。唯⼀终止持久化实

例生命周期的方式就是注销实例的请求。

非持久化的实例

会根据版本不同,采用不同方式维持健康状态:

  • Nacos1.0通过定时的心跳请求来进行续约,当超过⼀定时间内没有心跳进行续约时,该非持久化实例则终止生命周期
  • Nacos2.0通过 gRPC 长连接维持状态,当连接发生中断时,该非持久化实例则终止生命周期。当然,非持久化实例也可以通过注销实例的请求,主动终止其生命周期,但由于长连接和心跳续约,可能导致前⼀个实例数据的生命周期刚被终止移除,立刻又因心跳和长连接的补偿请求,再次开启实例的生命周期,导致注销失败假象。

9.3 集群的⽣命周期

集群作为服务和实例的⼀个中间层,因此集群的生命周期与实例和服务的生命周期均有关:

  • 集群的生命周期开始,与该集群【第⼀个实例】的生命周期同时开始,因为⼀个实例必归属⼀个集群
  • 当⼀个集群中不存在实例,集群生命周期不会立刻结束,而是等这服务的生命周期结束时,才会⼀起结束生命周期

9.4 元数据的⽣命周期

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

小结

各数据的生命周期图:

总结

本文主要介绍了 Nacos 注册中心中的服务数据模型及其生命周期。作为 Nacos 注册中心的内容核心,正确理解服务、实例及集群中的数据内容,以及他们之间的关系;知晓各个数据的生命周期,才能够理解 Nacos 注册中心的工作原理和工作流程。

生命周期的健康状态及维护健康状态的健康检查机制是接下来要详介内容。