背景
为了方便应用程序配置文件的管理,决定使用市面上流行的配置中心作为实现方案,由于配置中心的备选方案很多,我们需要结合目前项目的实际情况来进行技术选型
目前市面上流行的配置中心
- Disconf
- Spring-cloud-config
- Ctrip apollo
- Disconf
- Nacos
- 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,
|
|||
备注 | 官方已停止维护,4年未更新 |
进一步筛选
spring-cloud-config只支持java生态,而disconf已经官方停止维护,超过4年没有更新,故两者不考虑。
configMap强依赖k8s,必须应用先迁移到ks8容器后才能使用,另外UI支持过于简单,需要的功能例如权限控制、审计记录等几乎都没有。configMap的SDK也支持不佳,如果客户端需要获取配置,目前有如下使用四种方式来使用 ConfigMap 配置 Pod 中的容器:
- 在容器命令和参数内
- 容器的环境变量
- 在只读卷里面添加一个文件,让应用来读取
- 编写代码在 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,但日常需要的功能均大差不差,且使用简单易于上手,搭建环境也不需要额外的中间件依赖。