项目在考虑引入注册中心和配置中心,对比了下当前较流行的配置中心和注册中心,发现Nacos比较适合我们这种私有化部署比较多的场景。本文将对其介绍,后续将会从源码实现层面进行研究分享。
一、与其他产品对比
1.1 与其他配置中心对比
当前比较流行的配置中心就是Apollo,因此与Apollo进行对比。
对比项目/配置中心 | Apollo | Nacos |
---|---|---|
高可用 | 基于Eureka | 基于Raft,不需要额外中间件 |
多环境 | 以项目粒度为单位,每个项目下多环境 | 以环境粒度为单位,每个环境下多个项目 |
配置生效 | 秒级别热更新生效 | 秒级别热更新生效 |
版本管理 | 自动管理 | 自动管理 |
配置回滚 | 支持 | 支持 |
配置继承 | 支持配置继承,可以有公共配置,其他都来继承,适合微服务的场景 | 不支持 |
灰度发布 | 支持 | 支持 |
配置格式校验 | 支持 | 支持 |
审计 | 支持审计日志,可以清晰查看每次操作时变更的配置条目和变更前后对比 | 支持审计日志,仅记录了变更前的原记录,未展示变更的配置条目以及变更前后对比 |
权限管理 | 以项目粒度为单位对UI登录用户/客户端调用鉴权,不支持只读/读写粒度权限控制 | 以环境粒度为单位对UI登录用户/客户端调用鉴权,支持只读/读写粒度权限控制 |
监听查询 | 支持 | 支持 |
多语言 | Go,C++,Python,Java,.net,OpenAPI | Python,Java,Nodejs,Go,OpenAPI |
分布式高可用最小集群数量 | Config2+Admin3+Portal*2+Mysql=8 | Nacos*3+MySql=4 |
通信协议 | HTTP | HTTP、gRPC |
从上面可以看出,配置中心该有的功能两者都有,Apollo在功能上比Nacos更加完善。但是,Apollo在部署上依赖的太多,运维成本较高。此外,Apollo只是一个配置中心,Nacos还有注册中心,如果服务同时依赖注册中心和配置中心,只需要部署一套Nacos就可以满足需求,运维成本较低。
1.2 与其他注册中心对比
对比项目\注册中心 | Nacos | Eureka | Consul |
---|---|---|---|
依赖 | 无 | Zookeeper | 无 |
CAP模型 | AP+CP | AP | CP |
伸缩性 | Raft选举算法性能、可用性、容错性均比较好 | 使用广播同步信息,集群超过1000台机器后对Eureka集群压力很大 | Raft选举算法 |
健康检查方式 | TPC/HTTP/SQL/Client Beat | Client Beat | TCP/HTTP/gRPC/CMD |
负载均衡策略 | 权重/MetaData/Selector | Ribbon | Fabio |
跨中心同步 | 支持 | 不支持 | 支持 |
版本迭代 | 正常迭代 | 已不升级 | 正常迭代 |
集成支持 | SpringCloud/K8S | SpringCloud | SpringCloud/K8S |
访问协议 | HTTP/DNS/gRPC | HTTP | HTTP/DNS |
雪崩保护 | 支持 | 支持 | 不支持 |
自动注销实例 | 支持 | 支持 | 不支持 |
监听支持 | 支持 | 支持 | 支持 |
界面 | 中文 | 英文 | 英文 |
因Eureka 2.x已不再迭代,不会选用。从功能上来看,Nacos注册中心会更加完善。从UI上看,Nacos为中文界面,更符合国人习惯。因此,Nacos是更好的选择。
二、Nacos原理
2.1 系统架构
Nacos系统架构设计如下:
逻辑架构及组件:
整体架构分为用户层、业务层、内核层和插件,用户层解决易用性问题,业务层解决服务发现和配置管理功能,内核层解决分布式系统一致性、存储、高可用等核心问题,插件解决扩展性问题。
- 用户层:OpenAPI,Console,SDK,Agent,CLI。
- 业务层:服务管理,配置管理,元数据管理。
- 内核层:插件机制,事件机制,日志模块,回调机制,寻址模式,推送通道,容量管理,流量管理,缓存机制,启动模式,一致性协议,存储模块。
- 插件:NameService,CMDB,Metrics,Trace,接入管理,用户管理,权限管理,审计系统,通知系统。
2.2 配置中心设计
2.2.1 配置中心领域模型
- 命名空间(NameSpace):用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的Group或Data ID的配置。Namespace的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如数据库配置、限流阈值、降级开关)隔离等。如果在没有指定Namespace的情况下,默认使用public命名空间。
- 配置组(Group):Nacos中的一组配置集,是配置的维度之一,默认为DEFAULT_GROUP,常见的使用场景为不同的应用或组件使用了相同的配置项。
- 配置ID(Data ID):Nacos中的某个配置集的ID,是划分配置的维度之一,一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。
一种典型使用场景如下:
2.2.2 数据一致性
配置中心在实现上采用AP一致性协议。
- 对于Server间的一致性协议:
- 有DB,核心是保证Server与DB之前的数据一致性。Server之间完全对等的,数据写任何一个Server,优先持久化,然后异步通知其他节点到数据库中拉取最新配置值,并且通知写入成功。
- 无DB,Server间采用Raft协议保证数据一致性。
- 对于Client与Server之间的一致性,通过MD5值检验是否一致,不一致就拉取最新值。在2.x中,客户端会和Server端建立一条长连接,30秒一次长轮训,配置变更服务端推送变更配置列表,然后SDK拉取配置更新。
2.2.3 容灾
Nacos客户端会在本地生成配置的快照,当客户端无法连接到Nacos Server时,可以使用配置快照实现整体容灾能力,类似于缓存,会在适当的时机更新,但是并没有缓存过期的概念。
2.3 注册中心设计
2.3.1 注册中心数据模型
Nacos划分为服务、集群、实例三层。
- 服务:包括以下几个内容。
- 命名空间(Namespace):Nacos数据模型中最顶层的概念,可用于环境或者租户之前强隔离的场景。
- 分组(Group):次于命名空间的一种隔离概念,属于一个弱隔离概念,主要用于逻辑区分一些服务使用场景或不同应用的同名服务,比如同一个服务的测试分组和生产分组。
- 服务名(Name):服务实例的名字,用于描述该服务提供了某种功能或能力。
- 集群(Cluster):一组服务实例的一个逻辑抽象的概念,介于服务和实例之间,是一部分服务属性的下沉和实例属性的抽象,主要保存了有关健康检查的一些信息和数据。
- 健康检查类型:支持TCP,HTTP,MySQL,设置为NONE可以关闭健康检查。
- 健康检查端口:设置用于健康检查的端口。
- 是否使用实例端口进行健康检查:如果使用实例端口进行健康检查,将会使用实例定义中的网络端口进行健康检查,而不再使用上述设置的健康检查端口进行。
- 拓展数据:用于用户自定义扩展的元数据内容,形式为 K-V 。
- 实例(Instance):某个服务的具体提供能力的节点。
- 实例定义(开发运行场景)
- 网络IP地址:该实例的IP地址,在Nacos2.0版本后支持设置为域名。
- 网络端口:该实例的端口信息。
- 健康状态:通过健康检查的手段进行维护。
- 集群(Cluster):标示该实例归属于哪个逻辑集群。
- 拓展数据(extendData):用于用户自定义扩展的元数据内容,形式为K-V。
- 实例元数据(运维场景)
- 权重:浮点数,范围为0-10000。权重越大,分配给该实例的流量越大。
- 上线状态:标记该实例是否接受流量,优先级大于权重和健康状态。
- 拓展数据:不同于实例定义中的拓展数据,这个拓展数据是给予运维人员在不变动实例本身的情况下,快速地修改和新增实例的扩展数据,从而达到运维实例的作用。
- 实例定义(开发运行场景)
2.3.2 一致性
Nacos支持AP和CP两种并存的一致性协议,实现上,一个是基于简化的Raft的CP一致性,一个是基于自研协议Distroÿ