本文将从产品功能, 使用体验, 实施过程和性能 4 个纬度进行对比, 所有素材均来源于该开源项目的官网或 GitHub 项目页. 如果您对微服务配置中心的功能不是很了解, 可以看下以下的背景介绍, 若比较熟悉可以直接跳过.
[编者的话] 在撰写这篇技术选型的文章之前, 是比较犹豫的. 因为, 以其中一个开源项目开发者的身份, 去写一篇三个开源项目的对比, 即便很克制的去客观的比较, 也很难有信服力. 这就像, 既是参赛选手, 又想做裁判, 观众肯定是不买账的.
但最后, 仍然决定去写一篇配置中心的技术选型参考文, 是因为:
工作所需, 要做一款好用的开源产品, 去试用提供相似功能的开源产品是必要的环节, 以找出优势, 弥补不足;
用户所需, 对于提供相似功能的产品进行选型对比, 是引入某个开源项目必须要做的事, 如果有一份参考, 那么势必能提供一些帮助;(建议: 即便有一份可参考的材料, 技术选型的工作仍需要亲力亲为, 实际的业务场景和资源配置才是技术选型最重要的依据);
微服务配置中心是一个微服务组件, 而不是一个大的框架, 选型成本较小, 客观对比时不易走偏;
本文将从产品功能, 使用体验, 实施过程和性能 4 个纬度进行对比, 所有素材均来源于该开源项目的官网或 GitHub 项目页.
如果您对微服务配置中心的功能不是很了解, 可以看下以下的背景介绍, 若比较熟悉可以直接跳过.
为什么需要配置中心
配置实时生效:
传统的静态配置方式要想修改某个配置只能修改之后重新发布应用, 要实现动态性, 可以选择使用数据库, 通过定时轮询访问数据库来感知配置的变化. 轮询频率低感知配置变化的延时就长, 轮询频率高, 感知配置变化的延时就短, 但比较损耗性能, 需要在实时性和性能之间做折中. 配置中心专门针对这个业务场景, 兼顾实时性和一致性来管理动态配置.
配置管理流程:
配置的权限管控, 灰度发布, 版本管理, 格式检验和安全配置等一系列的配置管理相关的特性也是配置中心不可获取的一部分.
开源配置中心基本介绍
目前市面上用的比较多的配置中心有(按开源时间排序):
Disconf,2014 年 7 月百度开源的配置管理中心, 同样具备配置的管理能力, 不过目前已经不维护了, 最近的一次提交是两年前了.
Spring Cloud Config,2014 年 9 月开源, Spring Cloud 生态组件, 可以和 Spring Cloud 体系无缝整合.
Apollo,2016 年 5 月, 携程开源的配置管理中心, 具备规范的权限, 流程治理等特性.
Nacos,2018 年 6 月, 阿里开源的配置中心, 也可以做 DNS 和 RPC 的服务发现.
配置中心核心概念的对比
由于 Disconf 不再维护, 下面对比一下 Spring Cloud Config,Apollo 和 Nacos.
Spring Cloud Config,Apollo 和 Nacos 在配置管理领域的概念基本相同, 但是也存在一些不同的点, 使用配置的过程中会涉及到一些比较重要的概念.
应用
应用是客户端系统的基本单位, Spring Cloud Config 将应用名称和对应 Git 中的文件名称关联起来了, 这样可以起到多个应用配置相互隔离的作用. Apollo 的配置都是在某个应用下面的(除了公共配置), 也起到了多个应用配置相互隔离的作用. Nacos 的应用概念比较弱, 只有一个用于区分配置的额外属性, 不过可以使用 Group 来做应用字段, 可以起到隔离作用.
集群
不同的环境可以搭建不同的集群, 这样可以起到物理隔离的作用, Spring Cloud Config,Apollo,Nacos 都支持多个集群.
Label Profile & 环境 & 命名空间
Spring Cloud Config 可以使用 Label 和 Profile 来做逻辑隔离, Label 指远程仓库的分支, Profile 类似 Maven Profile 可以区分环境, 比如{application}-{profile}.properties.
Nacos 的命名空间和 Apollo 的环境一样, 是一个逻辑概念, 可以作为环境逻辑隔离. Apollo 中的命名空间指配置的名称, 具体的配置项指配置文件中的一个 Property.
配置管理功能的对比
作为配置中心, 配置的整个管理流程应该具备流程化能力.
灰度发布
配置的灰度发布是配置中心比较重要的功能, 当配置的变更影响比较大的时候, 需要先在部分应用实例中验证配置的变更是否符合预期, 然后再推送到所有应用实例.
Spring Cloud Config 支持通过 / bus/refresh 端点的 destination 参数来指定要更新配置的机器, 不过整个流程不够自动化和体系化.
Apollo 可以直接在控制台上点灰度发布指定发布机器的 IP, 接着再全量发布, 做得比较体系化.
Nacos 目前发布到 0.9 版本, 还不支持灰度发布.
权限管理
配置的变更和代码变更都是对应用运行逻辑的改变, 重要的配置变更常常会带来核弹的效果, 对于配置变更的权限管控和审计能力同样是配置中心重要的功能.
Spring Cloud Config 依赖 Git 的权限管理能力, 开源的 GitHub 权限控制可以分为 Admin,Write 和 Read 权限, 权限管理比较完善.
Apollo 通过项目的维度来对配置进行权限管理, 一个项目的 owner 可以授权给其他用户配置的修改发布权限.
Nacos 目前看还不具备权限管理能力.
版本管理 & 回滚
当配置变更不符合预期的时候, 需要根据配置的发布版本进行回滚. Spring Cloud Config,Apollo 和 Nacos 都具备配置的版本管理和回滚能力, 可以在控制台上查看配置的变更情况或进行回滚操作. Spring Cloud Config 通过 Git 来做版本管理, 更方便些.
配置格式校验
应用的配置数据存储在配置中心一般都会以一种配置格式存储, 比如 Properties,JSON,YAML 等, 如果配置格式错误, 会导致客户端解析配置失败引起生产故障, 配置中心对配置的格式校验能够有效防止人为错误操作的发生, 是配置中心核心功能中的刚需.
Spring Cloud Config 使用 Git, 目前还不支持格式检验, 格式的正确性依赖研发人员自己.
Apollo 和 Nacos 都会对配置格式的正确性进行检验, 可以有效防止人为错误.
监听查询
当排查问题或者进行统计的时候, 需要知道一个配置被哪些应用实例使用到, 以及一个实例使用到了哪些配置.
Spring Cloud Config 使用 Spring Cloud Bus 推送配置变更, Spring Cloud Bus 兼容 RabbitMQ,Kafka 等, 支持查询订阅 Topic 和 Consumer 的订阅关系.
Apollo 可以通过灰度实例列表查看监听配置的实例列表, 但实例监听的配置 (Apollo 称为命名空间) 目前还没有展示出来.
Nacos 可以查看监听配置的实例, 也可以查看实例监听的配置情况.
基本上, 这三个产品都具备监听查询能力, 在我们自己的使用过程中, Nacos 使用起来相对简单, 易用性相对更好些.
多环境
在实际生产中, 配置中心常常需要涉及多环境或者多集群, 业务在开发的时候可以将开发环境和生产环境分开, 或者根据不同的业务线存在多个生产环境. 如果各个环境之间的相互影响比较小(开发环境影响到生产环境稳定性), 配置中心可以通过逻辑隔离的方式支持多环境.
Spring Cloud Config 支持 Profile 的方式隔离多个环境, 通过在 Git 上配置多个 Profile 的配置文件, 客户端启动时指定 Profile 就可以访问对应的配置文件.
Apollo 也支持多环境, 在控制台创建配置的时候就要指定配置所在的环境, 客户端在启动的时候指定 JVM 参数 ENV 来访问对应环境的配置文件.
Nacos 通过命名空间来支持多环境, 每个命名空间的配置相互隔离, 客户端指定想要访问的命名空间就可以达到逻辑隔离的作用.
多集群
当对稳定性要求比较高, 不允许各个环境相互影响的时候, 需要将多个环境通过多集群的方式进行物理隔离.
Spring Cloud Config 可以通过搭建多套 Config Server,Git 使用同一个 Git 的多个仓库, 来实现物理隔离.
Apollo 可以搭建多套集群, Apollo 的控制台和数据更新推送服务分开部署, 控制台部署一套就可以管控多个集群.
Nacos 控制台和后端配置服务是部署在一起的, 可以通过不同的域名切换来支持多集群.
配置实时推送的对比
当配置变更的时候, 配置中心需要将配置实时推送到应用客户端.
Nacos 和 Apollo 配置推送都是基于 HTTP 长轮询, 客户端和配置中心建立 HTTP 长联接, 当配置变更的的时候, 配置中心把配置推送到客户端.
Spring Cloud Config 原生不支持配置的实时推送, 需要依赖 Git 的 webHook,Spring Cloud Bus 和客户端 / bus/refresh 端点:
基于 Git 的 WebHook, 配置变更触发 server 端 refresh
Server 端接收到请求并发送给 Spring Cloud Bus
Spring Cloud Bus 接到消息并通知给客户端
客户端接收到通知, 请求 Server 端获取最新配置
整体比较下来, Nacos 和 Apollo 在配置实时推送链路上是比较简单高效的, Spring Cloud Config 的配置推送引入 Spring Cloud Bus, 链路较长, 比较复杂.
部署结构 & 高可用的对比
Spring Cloud Config
Spring Cloud Config 包含 config-server,Git 和 Spring Cloud Bus 三大组件:
config-server 提供给客户端获取配置;
Git 用于存储和修改配置;
Spring Cloud Bus 通知客户端配置变更;
本地测试模式下, Spring Cloud Bus 和 config-server 需要部署一个节点, Git 使用 GitHub 就可以. 在生产环境中, Spring Cloud Config,config-server 需要部署至少两个节点. Spring Cloud Bus 如果使用 RabbitMQ, 普通集群模式至少需要两个节点.
Git 服务如果使用 GitHub 就不用考虑高可用问题, 如果考虑到安全性要自建 Git 私有仓库, 整体的成本比较高. Web 服务可以部署多节点支持高可用, 由于 Git 有数据的一致性问题, 可以通过以下的方式来支持高可用:
Git+Keepalived 冷备模式, 当主 Git 挂了可以马上切到备 Git;
Git 多节点部署, 存储使用网络文件系统或者通过 DRBD 实现多个 Git 节点的数据同步;
Apollo
Apollo 分为 MySQL,Config Service,Admin Service,Portal 四个模块:
MySQL 存储 Apollo 元数据和用户配置数据;
Config Service 提供配置的读取, 推送等功能, 客户端请求都是落到 Config Service 上;
Admin Service 提供配置的修改, 发布等功能, Portal 操作的服务就是 Admin Service;
Portal 提供给用户配置管理界面;
本地测试 Config Service,Admin Service,Portal 三个模块可以合并一起部署, MySQL 单独安装并创建需要的表结构. 在生产环境使用 Apollo,Portal 可以两个节点单独部署, 稳定性要求没那么高的话, Config Service 和 Admin Service 可以部署在一起, 数据库支持主备容灾.
Nacos
Nacos 部署需要 Nacos Service 和 MySQL:
Nacos 对外提供服务, 支持配置管理和服务发现;
MySQL 提供 Nacos 的数据持久化存储;
单机模式下, Nacos 可以使用嵌入式数据库部署一个节点, 就能启动. 如果对 MySQL 比较熟悉, 想要了解整体数据流向, 可以安装 MySQL 提供给 Nacos 数据持久化服务. 生产环境使用 Nacos,Nacos 服务需要至少部署三个节点, 再加上 MySQL 主备.
整体来看
Nacos 的部署结构比较简单, 运维成本较低. Apollo 部署组件较多, 运维成本比 Nacos 高. Spring Cloud Config 生产高可用的成本最高.
多语言支持的对比
一个公司的各个系统可能语言不尽相同, 现在使用的比较多的比如 C++,Java,PHP,Python,Node.JS, 还有 Go 等. 引入配置中心之后, 配置中心要想让多语言的系统都能享受到动态配置的能力, 需要支持多语言生态.
多语言支持
Spring Cloud 服务于 Java 生态, 一开始只是针对 Java 微服务应用, 对于非 Java 应用的微服务调用, 可以使用 Sidecar 提供了 HTTP API, 但动态配置方面还不能很好的支持.
Apollo 已经支持了多种语言, 并且提供了 open API. 其他不支持的语言, Apollo 的接入成本相对较低.
Nacos 支持主流的语言, 例如 Java,Go,Python,Node.JS,PHP 等, 也提供了 open API.
迁移支持
国内主流的互联网公司仍是以 Java 为主, 除了原生 Java SDK, 在对整个 Java 生态, 比如 Spring Boot 和 Spring Cloud 的支持上, 三个产品都是支持的.
Spring Cloud Config 原生就支持 Spring Boot 和 Spring Cloud,Nacos 通过 Spring Cloud for Alibaba 支持 Spring Boot 和 Spring Cloud 生态, 符合 Spring 生态中的标准实现方式, 可以无缝从 Spring Cloud Conig 迁移到 Nacos.
Apollo 支持 Spring Boot 和 Spring Cloud 项目, 但是实现方式不同于标准, 无法做无缝迁移, 从 Spring Cloud 迁移到 Apollo, 存在代码改造和兼容性成本.
性能对比
性能也是配置中心绕不过的一环, 在同样的机器规格下, 如果能支撑更大的业务量, 势必能替公司节省更多的资源成本, 提高资源利用率. 应用客户端对配置中心的接口操作有读, 写和变更通知, 由于变更通知需要大量的客户端实例, 不好模拟测试场景, 下面仅对读和写操作做了测试.
硬件环境
Nacos 和 Apollo 使用同样的数据库(32C128G), 部署 Server 服务的机器使用的 8C16G 配置的容器, 磁盘是 100G SSD.
版本
Spring Cloud Config 使用 2.0.0.M9 版本, Apollo 使用 1.2.0 release 版本, Nacos 使用 0.5 版本.
单机读场景
客户端测试程序通过部署多台机器, 每台机器开启多个线程从配置中心读取不同的配置(3000 个).Nacos QPS 可以达到 15000,Apollo 分为读内存缓存和从数据库中读两种方式, 从数据库中读能达到 7500, 从内存读缓存性能可以达到 9000QPS.Spring Cloud Config 使用 jGit 读写 Git, 由于有客户端限制, 单机读能力被限制在 7QPS.
3 节点读场景
将配置中心的压测节点数都部署成 3 个节点. Nacos QPS 可以达到 45000 QPS,Apollo 读内存缓存可以达到 27000 QPS.Nacos 和 Apollo 由于读场景各个节点是独立的, 基本就是单机读场景的 3 倍关系. Spring Cloud Config 三个节点读能力可以到达 21QPS.
单机写场景
同样的方式, 多台机器同时在配置中心修改不同的配置. Nacos QPS 可以达到 1800,Apollo 未使用默认的数据库连接池(10)QPS 只能达到 800 QPS(CPU 未压满), 调整连接池至 100 可以达到 1100 QPS(CPU 压满).Git 在提交同一个项目的时候会加锁, 单机 Git 写能在 5QPS 左右, Spring Cloud Config 在使用的时候以一个项目作为数据源, 写能力受到 Git 限制.
3 节点写场景
同样的方式, 将配置中心的压测节点数都部署成 3 个节点. Nacos QPS 可以达到 6000,Apollo 可以达到 3300 QPS(CPU 压满), 此时 MySQL 数据库因为配置较高, 未成为性能瓶颈. Spring Cloud Config 三个节点时候, Git 也是一个节点, 写 QPS 为 5.
整体上来看, Nacos 的读写性能最高, Apollo 次之, Spring Cloud Config 的依赖 Git 场景不适合开放的大规模自动化运维 API.
功能特性对比总结
这里列一个表格总结一下三个产品的功能特点.
总的来说, Apollo 和 Nacos 相对于 Spring Cloud Config 的生态支持更广, 在配置管理流程上做的更好. Apollo 相对于 Nacos 在配置管理做的更加全面, 不过使用起来也要麻烦一些. Nacos 使用起来相对比较简洁, 在对性能要求比较高的大规模场景更适合.
此外, Nacos 除了提供配置中心的功能, 还提供了动态服务发现, 服务共享与管理的功能, 降低了服务化改造过程中的难度.
以上, 我们从产品功能, 使用体验, 实施过程和性能 4 个纬度对 Spring Cloud Config,Apollo 和 Nacos 进行对比. 但对于一个开源项目的选型, 除了以上这 4 个方面, 项目上的人力投入(迭代进度, 文档的完整性), 社区的活跃度(issue 的数量和解决速度, Contributor 数量, 社群的交流频次等), 社区的规范程度(免责说明, 安全性说明等), 这些可能才是用户更关注的内容.
作者: 风卿, Nacos 社区 committer
来源: http://server.51cto.com/Micro-595009.htm