关于后端:Nacos-注册中心的设计原理让你的应用轻松实现高效注册与发现

3次阅读

共计 3500 个字符,预计需要花费 9 分钟才能阅读完成。

当利用开始脱离单机运行和拜访时,服务发现就诞生了。目前的网络架构是每个主机都有⼀个独立的 IP 地址,服务发现根本都是通过某种形式获取到服务所部署的 IP 地址。

DNS 协定是最早将⼀个网络名称翻译为网络 IP 的协定,在最后的架构选型中,DNS+LVS+Nginx 根本满足所有 RESTful 服务的发现,此时服务的 IP 列表通常配置在 nginx 或 LVS。起初呈现 RPC 服务,服务的高低线更加频繁,人们开始寻求⼀种可能反对动静高低线并且推送 IP 列表变动的注册核心产品。

互联网软件行业广泛热捧开源产品,因为开源产品代码通明、能够参加共建、有社区进行交换和学习,当然更重要是收费。集体开发者或者中小型公司往往会将开源产品作为选型首选。

1 开源产品

1.1 Zookeeper

经典服务注册核心产品(尽管它最后的定位并不在于此),在很长⼀段时间里,是国人在提起 RPC 服务注册核心时心里想到的唯⼀抉择,这很大水平上与 Dubbo 在中国的遍及水平无关。

1.2 Consul 和 Eureka

都呈现于 2014 年:

  • Consul 在设计上把很多分布式服务治理上要用到的性能都蕴含在内,能够反对服务注册、健康检查、配置管理、Service Mesh 等
  • Eureka 借微服务概念风行,与 SpringCloud 生态的深度联合,也获取了大量的用户

1.3 Nacos

则携带着阿里巴巴大规模服务生产教训,试图在服务注册和配置管理这个市场上,提供给用户⼀个新的抉择。

图 1 服务发现:

1.4 开源产品的劣势

开发人员能够去浏览源代码,了解产品的功能设计和架构设计,同时也能够通过本地部署来测试性能,随之而来的是各种产品的比照文章。

不过以后对于注册核心的比照,往往停留在外表的性能比照上,对架构或者性能并没深入探讨。

1.5 痛点

是服务注册核心往往暗藏在服务框架背地,作为默默反对的产品。优良的服务框架往往反对多种配置核心,然而注册核心的抉择仍然强关联与服务框架,⼀种广泛的状况是⼀种服务框架会带⼀个默认的服务注册核心。这样尽管免去了用户在选型上的懊恼,然而单个注册核心的局限性,导致用户应用多个服务框架时,必须部署多套齐全不同的注册核心,这些注册核心之间的数据协同也是⼀个问题。

本文从各个角度深度介绍 Nacos 注册核心的设计原理,并试图从咱们的教训和调研中总结和论述服务注册核心产品设计上应该去遵循和思考的要点。

2 数据模型

注册核心的外围数据:

  • 服务的名字
  • 它对应的网络地址

当服务注册了多个实例时,咱们须要对不衰弱的实例过滤或针对实例的⼀些特色进行流量调配,就须要在实例存储⼀些如衰弱状态、权重等属性。随服务规模扩充,慢慢的又须要在整个服务级别设定⼀些权限规定、以及对所有实例都失效的⼀些开关,于是在服务级别又会设立⼀些属性。再往后,咱们又发现单个服务的实例又会有划分为多个子集的需要,例如⼀个服务是多机房部署的,那么可能须要对每个机房的实例做不同的配置,这样又须要在服务和实例之间再设定⼀个数据级别。

比照

  • Zookeeper 没有针对服务发现设计数据模型,它的数据是以⼀种更加形象的树形 K-V 组织的,因而实践上能够存储任何语义的数据
  • Eureka 或者 Consul 都做到实例级的数据扩大,可满足大部分的场景,不过无奈满足大规模和多环境的服务数据存储
  • Nacos 在通过外部多年生产教训后提炼出的数据模型,则是⼀种服务 - 集群 - 实例的三层模型。根本满足服务在所有场景下的数据存储和治理。

Nacos 的数据模型尽管绝对简单,但它不强制你应用它外面的所有数据,在大多数场景下,你能够抉择疏忽这些数据属性,此时可降维成和 Eureka 和 Consul ⼀样的数据模型。

数据的隔离模型

作为⼀个共享服务型的组件,须要可能在多个用户或者业务方应用状况下,保证数据的隔离和平安,这在略微大⼀点的业务场景中十分常见。另⼀方面服务注册核心往往会反对云上部署,此时就要求服务注册核心的数据模型可能适配云上的通用模型。

Zookeeper、Consul 和 Eureka 在开源层面都没有很明确的针对服务隔离的模型,Nacos 则在⼀开始就思考到如何让用户可能以多种维度进行数据隔离,同时可能平滑的迁徙到阿里云上对应的商业化产品。

图 3 服务的四层的数据逻辑隔离模型:

用户账号对应可能是⼀个企业或独立的个体,这个数据⼀般状况不会透传到服务注册核心。⼀个用户账号可新建多个命名空间,每个命名空间对应⼀个客户端实例,这个命名空间对应的注册核心物理集群是能够依据规定进行路由的,这样能够让注册核心外部的降级和迁徙对用户无感知,同时依据用户的级别,为用户提供不同服务级别的物理集群。

再往下是服务分组和服务名组成的二维服务标识,能够满足接口级别的服务隔离。

Nacos 1.0.0 介绍的另外⼀个新个性是:长期实例和长久化实例。在定义上辨别长期实例和长久化实例的要害是健康检查的形式。长期实例应用客户端上报模式,而长久化实例应用服务端反向探测模式。长期实例须要可能主动摘除不衰弱实例,而且无需长久化存储实例,那么这种实例就实用于类 Gossip 的协定。左边的长久化实例应用服务端探测的健康检查形式,因为客户端不会上报心跳,那么天然就不能去主动摘除下线的实例。

图 4 长期实例和长久化实例:

大中型公司,这两种类型的服务都有:

  • ⼀些根底组件如数据库、缓存等,这些往往不能上报心跳,这种类型的服务在注册时,就须要作为长久化实例注册
  • 下层的业务服务,例如微服务或者 Dubbo 服务,服务的 Provider 端反对增加汇报心跳的逻辑,可应用动静服务的注册形式

Nacos 2.0 沿用长久化及非长久化的设定,但有调整。Nacos 1.0 中长久化及非长久化的属性是作为实例的⼀个元数据进行存储和辨认。导致同⼀个服务下可同时存在长久化实例和非长久化实例。但理论应用中,这种模式:

  • 会给运维人员带来极大的困惑和运维复杂度
  • 从零碎架构来看,⼀个服务同时存在长久化及非长久化实例的场景也是存在⼀定矛盾

导致该能力事实上未被宽泛应用。为简化 Nacos 的服务数据模型,升高运维复杂度,晋升 Nacos 易用性,在 Nacos2.0 中:

  • 是否长久化的数据抽象至服务级别
  • 不再容许⼀个服务同时存在长久化实例和非长久化实例,实例的长久化属性继承自服务的长久化属性

3 数据⼀致性

分布式系统永恒话题,协定层面上看,⼀致性的选型曾经很长时间没有新的成员退出了。目前来看根本

可归两家:

  • 基于 Leader 的非对等部署的单点写⼀致性
  • 对等部署的多写⼀致性

选用服务注册核心,没有⼀种协定能笼罩所有场景,如:

  • 当注册的服务节点不会定时发送心跳到注册核心时,强⼀致协定看起来是唯⼀的抉择,因为无奈通过心跳来进行数据的弥补注册,第⼀次注册就必须保证数据不会失落
  • 而当客户端会定时发送心跳来汇报衰弱状态时,第⼀次的注册的成功率并不是十分要害(当然也很要害,只是相对来说咱们容忍数据的大量写失败),因为后续还能够通过心跳再把数据弥补上来,此时 Paxos 协定的单点瓶颈就会不太划算了,这也是 Eureka 为什么不采纳 Paxos 协定而采纳自定义的 Renew 机制

这两种数据⼀致性协定有各自应用场景,对服务注册需要不同,就会导致应用不同协定。Zookeeper 在 Dubbo 体系下体现出的行为,其实采纳 Eureka 的 Renew 机制更适合,因为 Dubbo 服务往 Zookeeper 注册的就是长期节点,须要定时发心跳到 Zookeeper 来续约节点,并容许服务下线时,将 Zookeeper 上相应的节点摘除。Zookeeper 应用 ZAB 虽保证数据的强⼀致,然而它的机房容灾能力的不足,无奈适应⼀些大型场景。

Nacos 因为要反对多种服务类型的注册,并可能具备机房容灾、集群扩大等必不可少的能力,1.0.0 正式反对 AP 和 CP 两种⼀致性协定并存。1.0.0 重构数据的读写和同步逻辑,将与业务相干的 CRUD 与底层的⼀致性同步逻辑进行了分层隔离。而后将业务的读写(次要是写,因为读会间接应用业务层的缓存)形象为 Nacos 定义的数据类型,调用⼀致性服务进行数据同步。在决定应用 CP 还是 AP ⼀致性时,应用⼀个代理,通过可管制的规定进行转发。

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

图 5 Nacos ⼀致性协定:

本文由博客一文多发平台 OpenWrite 公布!

正文完
 0