朱鹏飞,Github ID: nkorange,Nacos 注册中心等模块主要贡献者,阿里巴巴中间件高级开发工程师。
编者按:
开源产品受开发者热捧,是因为其代码透明、可以参与共建、有社区进行交流和学习,当然更重要的是开源产品的接入成本低。个人开发者或者中小型公司往往会将开源产品作为选型首选。
开发者通过阅读源代码,理解产品的功能设计和架构设计,同时也可以通过本地部署来测试性能,随之而来的是对各类开源产品的对比,用以选型。不过当前关于微服务注册中心的对比,大多聚焦在功能上的对比,对架构或者性能的深入探讨,比较少见。
另一方面,作为默默支持的产品,服务注册中心往往隐藏在服务框架背后。优秀的服务框架往往会支持多种配置中心,但是注册中心的选择依然与服务框架强关联,普遍的情况是一种服务框架会带一个默认的服务注册中心。这样虽然免去了用户在选型上的烦恼,但是单个注册中心的局限性,导致用户使用多个服务框架时,必须部署多套完全不同的注册中心,这些注册中心之间的数据协同是一个问题。
本文来自Nacos社区,作者是Nacos Committer朱鹏飞,作者力求公正和客观的去看待主流微服务注册中心的各个维度。本文不仅仅包含常见服务注册中心产品的对比,也试图从Nacos的经验和调研中总结并阐述服务注册中心产品设计上应该去遵循和考虑的要点,文章篇幅较长,若您有不同的看法,欢迎在文末留言,或到Nacos @GitHub 提issue。
前言
服务发现是一个古老的话题,当应用开始脱离单机运行和访问时,服务发现就诞生了。
目前的网络架构是每个主机都有一个独立的IP地址,那么服务发现基本上都是通过某种方式获取到服务所部署的IP地址。DNS协议是最早将一个网络名称翻译为网络IP的协议,在最初的架构选型中,DNS+LVS+Nginx基本可以满足所有的RESTful服务的发现,此时服务的IP列表通常配置在Nginx或者LVS。后来出现了RPC服务,服务的上下线更加频繁,人们开始寻求一种能够支持动态上下线并且推送IP列表变化的注册中心产品。
ZooKeeper是一款经典的服务注册中心产品(虽然它最初的定位并不在于此),在很长一段时间里,它是国人在提起RPC服务注册中心时心里想到的唯一选择,这很大程度上与Dubbo在中国的普及程度有关。Consul和Eureka都出现于2014年,Consul在设计上把很多分布式服务治理上要用到的功能都包含在内,可以支持服务注册、健康检查、配置管理、Service Mesh等。而Eureka则借着微服务概念的流行,与SpringCloud生态的深度结合,也获取了大量的用户。去年开源的Nacos,则携带着阿里巴巴大规模服务生产经验,试图在服务注册和配置管理这个市场上,提供给用户一个新的选择。
图1 服务发现
数据模型
注册中心的核心数据是服务的名字和它对应的网络地址,当服务注册了多个实例时,我们需要对不健康的实例进行过滤或者针对实例的一些特征进行流量的分配,那么就需要在实例上存储一些例如健康状态、权重等属性。随着服务规模的扩大,渐渐的又需要在整个服务级别设定一些权限规则、以及对所有实例都生效的一些开关,于是在服务级别又会设立一些属性。再往后,我们又发现单个服务的实例又会有划分为多个子集的需求,例如一个服务是多机房部署的,那么可能需要对每个机房的实例做不同的配置,这样又需要在服务和实例之间再设定一个数据级别。
Zookeeper没有针对服务发现设计数据模型,它的数据是以一种更加抽象的树形K-V组织的,因此理论上可以存储任何语义的数据。而Eureka或者Consul都是做到了实例级别的数据扩展,这可以满足大部分的场景,不过无法满足大规模和多环境的服务数据存储。Nacos在经过内部多年生产经验后提炼出的数据模型,则是一种服务-集群-实例的三层模型。如上文所说,这样基本可以满足服务在所有场景下的数据存储和管理。
图2 服务的分级模型
Nacos的数据模型虽然相对复杂,但是它并不强制你使用它里面的所有数据,在大多数场景下,你可以选择忽略这些数据属性,此时可以降维成和Eureka和Consul一样的数据模型。
另外一个需要考虑的是数据的隔离模型,作为一个共享服务型的组件,需要能够在多个用户或者业务方使用的情况下,保证数据的隔离和安全,这在稍微大一点的业务场景中非常常见。另一方面服务注册中心往往会支持云上部署,此时就要求服务注册中心的数据模型能够适配云上的通用模型。Zookeeper、Consul和Eureka在开源层面都没有很明确的针对服务隔离的模型,Nacos则在一开始就考虑到如何让用户能够以多种维度进行数据隔离,同时能够平滑的迁移到阿里云上对应的商业化产品。
图3 服务的逻辑隔离模型
Nacos提供了四层的数据逻辑隔离模型,用户账号对应的可能是一个企业或者独立的个体,这个数据一般情况下不会透传到服务注册中心。一个用户账号可以新建多个命名空间,每个命名空间对应一个客户端实例,这个命名空间对应的注册中心物理集群是可以根据规则进行路由的,这样可以让注册中心内部的升级和迁移对用户是无感知的,同时可以根据用户的级别,为用户提供不同服务级别的物理集群。再往下是服务分组和服务名组成的二维服务标识,可以满足接口级别的服务隔离。
Nacos 1.0.0介绍的另外一个新特性是:临时实例和持久化实例。在定义上区分临时实例和持久化实例的关键是健康检查的方式。临时实例使用客户端上报模式,而持久化实例使用服务端反向探测模式。临时实例需要能够自动摘除不健康实例,而且无需持久化存储实例,那