配置中心选型调研

背景

为了方便应用程序配置文件的管理,决定使用市面上流行的配置中心作为实现方案,由于配置中心的备选方案很多,我们需要结合目前项目的实际情况来进行技术选型

目前市面上流行的配置中心

  1. Disconf
  2. Spring-cloud-config
  3. Ctrip apollo
  4. Disconf
  5. Nacos
  6. ConfigMap

目前系统的现状

  • 编程语言:Java、Golang;以 Golang 为主,Java 为辅,大部分应用已经从Java切换成了 Golang ,但由于历史原因,部分项目组和少量的项目使用的是 Java 语言
  • 人员结构:大部分同事做业务开发,对中间件的了解不是太多
  • 系统部署:由于公司涉及到跨国业务,后续有可能考虑异地多活的涉及

基于上述考虑,配置中心需要具备:

  • 易用性:使用起来比较简单,对于业务开发的同事,学习起来比较容易,能够快速上手
  • 高可用:配置中心应避免单点故障,即使配置中心宕机,对于存量的配置信息也需要能够正常访问
  • 多语言:至少支持两种语言(Java + Golang),若有SDK更佳
  • 系统改造小:业务系统侵入性低,用较小的代价完成配置中心的集成
  • 多数据中心
  • 易维护:配置中心的运维成本越低越好,尽量减少运维人员的参与
  • 支持UI:通过界面,可以完成配置文件的上传、修改、删除

在满足以上条件的基础上,从功能的丰富程度来讲,若具备如下功能有限考虑:

  • 鉴权:基于安全性考虑,配置文件,需要通过鉴权的方式获取
  • 审计:对于配置文件的修改,可以追历史溯修改记录
  • 灰度
  • 性能

初步筛选

功能点 spring-cloud-config ctrip apollo nacos configMap disconf
易用性 第三方UI界面简单,易上手 UI界面复杂,中文文档充分,有一定的学习成本 UI界面简单,中文文档充分,易上手 UI界面过于简单原始,业务开发同事需要一定的k8s知识,否则需要运维配合操作
高可用 基于eureka实现集群模式 基于eureka实现集群模式 基于raft算法内部选举,不需要额外的中间件即可支持集群模式
配置生效 默认不支持配置热更新,需要集成其他组件才能实现热更新功能 秒级别热更新生效 秒级别热更新生效 秒级别热更新生效
多语言 只支持java 官方SDK: java、.net;第三方SDK: Go、PHP;支持HTTP API调用 官方SDK: java、Go、Python等;支持HTTP API调用 SDK: Java(不支持配置更改监听);可以编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap
改造成本 配合spring框架,几乎无代码改动,仅修改配置文件即可 集成SDK后代码侵入低 集成SDK后代码侵入低 强依赖k8s,且SDK缺乏,需要编写代码自实现相关功能
多数据中心 支持 支持 支持
多环境 以项目为颗粒度单位,每个项目下多个环境 以环境为颗粒度单位,每个环境下多个项目
易维护 除了注册中心应用本身,还需要额外维护Git和eureka 除了注册中心应用本身,还需要额外维护eureka 除了注册中心应用本身,不需要额外维护中间件 kubernetes子集,维护成本低
UI支持 官方不支持UI可集成第三方UI实现 官方自带UI 官方自带UI 不支持
鉴权 以项目为颗粒度对UI登录用户/客户端调用鉴权,不支持只读/读写颗粒度权限控制 以环境为颗粒度对UI登录用户/客户端调用鉴权,支持只读/读写颗粒度的权限控制
审计 支持审计日志,可以清晰查看每次操作时变更的配置条目和变更前后对比 支持审计日志,仅记录了变更前的原记录,未展示变更的配置条目以及变更前后对比
灰度 对指定IP集灰度发布 对指定IP集灰度发布
性能 官方称比spring-cloud-config快 官方压测3节点8核16G:写TPS 4214/读QPS 23013,https://nacos.io/zh-cn/docs/nacos-config-benchmark.html
备注 官方已停止维护,4年未更新

进一步筛选

spring-cloud-config只支持java生态,而disconf已经官方停止维护,超过4年没有更新,故两者不考虑。

configMap强依赖k8s,必须应用先迁移到ks8容器后才能使用,另外UI支持过于简单,需要的功能例如权限控制、审计记录等几乎都没有。configMap的SDK也支持不佳,如果客户端需要获取配置,目前有如下使用四种方式来使用 ConfigMap 配置 Pod 中的容器:

  1. 在容器命令和参数内
  2. 容器的环境变量
  3. 在只读卷里面添加一个文件,让应用来读取
  4. 编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap

这几种方案不仅需要额外的代码来实现逻辑,前3种方案不能实现配置更改监听,而第4种方案的代码改造量较大。再加上configMap对鉴权、审计、灰度发布等功能并未支持,所以configMap也不考虑使用。

apollo与nacos两者对于要求的功能都基本实现,apollo的UI界面复杂,有一定的学习成本,但对于审计功能实现比nacos更好,虽然官方未提供Golang版本的SDK,但有不少第三方SDK可以使用,而且本身也提供了HTTP协议的API。nacos的UI界面相当简单,即使不看文档也能轻松上手,且nacos本身不仅支持配置中心,也支持注册中心,但对于审计功能实现不如apollo,仅记录了变更前的原记录,未展示变更的配置条目以及变更前后对比,不能直观地查看每次记录的变更内容。

结论

如果仅仅只考虑使用配置中心,apollo虽然操作有些复杂,但功能更加完善。如果不仅使用配置中心,还需要使用注册中心,建议使用nacos,虽然功能实现略差于apollo,但日常需要的功能均大差不差,且使用简单易于上手,搭建环境也不需要额外的中间件依赖。