如何做好一个配置中心

2022-11-08 11:21:53 浏览数 (1)

我们知道,在程序中不应该把代码或流程写死,而应该把一些流程提取成开关、变量等。这样,就可以在不改变代码的情况下,在程序运行时执行不同的功能。这些开关、变量的集合一般放在一个或者多个文件里,称之为配置文件。一般来说,大部分程序都会存在这个文件,既然有文件,就需要管理。尤其是现在微服务化的趋势下,服务拆分,服务数量变多,配置文件的数量也跟着增加,就需要一个中心化的服务来管控这些配置文件,我们称之为配置中心,它一般会提供以下能力:

  • 配置的集中化管理,统一标准。
  • 配置的安全存储,不丢失。
  • 下发配置到服务,并支持自动更新。
  • 敏感配置的加密,权限管控。
  • 高可用,配置中心作为系统的关键节点,必须保证可用性。
  • 接入成本低,一般来说,刚开始以业务为主,对配置文件的管理需求没那么着急,等业务稳定才会考虑建立配置中心。那么,如何快速接入,快速切换,就很重要了。

那么,如何才能做好一个配置中心?下面列出几种可行的方案,并对比了其中的区别和优缺点。

Git 配置中心

配置信息存到 Git,比如:Spring 的 ConfigServer。这种方式利用了 Git 的存储特性和保存历史提交的特性,开发量小,接入简单,架构图如下:

在写入端,管理员通过 git push推送配置到仓库,并且能通过 git 提供的历史提交、权限管理等功能,对配置进行集中化管理,企业的 git 仓库一般也都会备份,所以数据不容易丢失。

在获取端,git 的弊端就比较明显了,你不能直接在程序中访问 git 获取配置,只能用个服务做中转,它根据程序的元信息去 git 仓库取配置,也不支持自动更新(虽然可以利用 git webhook,但是中转服务如何通知到程序,还是个问题。)而且加密解密也只能做到中转服务里,发送给程序的配置文件是不能加密的,不然程序没办法读取。

最后,Git 本身是单点服务,要是升级个版本或者做些运维操作时候,把 git 服务器弄挂了,就没办法获取配置了。

总而言之,读者可以发现,如果使用 git,其实整个系统中最关键的节点是中转服务,也就是那个 ConfigServer,可是既然要满足一个配置中心的所有要求,需要对这个 ConfigServer 进行开发迭代,那还不如把配置文件存到 Mysql 里,Mysql 相对更稳定,运维经验成熟,也容易扩展一些。

Apollo 配置中心

Apollo 就是这样做的,它没有依赖 git 去实现历史版本、权限等功能,全部由自己实现,它的架构图如下(从官网下载):

Apollo 确实是配置中心的标杆级项目,基本实现了一个配置中心的所有该有的功能,也十分契合当今微服务化、分布式的趋势,无需吹嘘它的功能多么多么强大,明者自鉴。只需说它的一个最大缺点,这个缺点正是源自它众多的功能 --- 它太复杂了。

我们不说如上的架构图,一个新手能不能看懂。就说它提供的命名空间、集群、环境、注册中心等等概念,就不是一下子能快速上手的。而且这么多功能在它的管理后台上,老实说组织的确实比较乱,东一块西一块的,没有层级划分。

我感觉 Apollo 和 git 配置中心正好相反,git 配置中心架构简单,功能不丰富;Apollo 提供了所有的能力,架构也是非常复杂。

Nacos 配置中心

随着云原生时代的来临,越来越多的组织在它们的技术架构中添加注册中心,以处理越来越多的微服务之间的发现和通信问题。Nacos 就是开源的注册中心中的佼佼者,它在 2.0 版本中又增加了配置中心的功能,让配置中心和注册中心得以合并。

Nacos 的问题主要是它不是专注于配置中心,提供的功能相对比较薄弱。比如:只有 java 的客户端,其它语言客户端是社区贡献,文档方面会差一些;不支持配置的加密解密(新版本支持了,但是需要编译,工作量大);自动更新支持的不是很好等等。

Nacos 目前还在蓬勃发展,也是属于 Java 世界中配置中心的比较好的一个选择。

自研配置中心

最后剩下的一类,就是不使用开源方案,全自研。自研的好处就是可以适应内部项目,便于迭代和掌控。而且,配置中心说到底,也不是一个十分复杂的项目,自研起来并没有特别的难点。

自研的配置中心一般类似于 Apollo和 Nacos,通过 Mysql 来存储配置,并提供一个管理界面。可以理解为对这两个项目进行模仿和改造,虽然会有些不同,但殊途同归,基本上是差不了多少的。

这里还有一类自研的配置中心,用的不是 mysql 存储配置,而是 ETCD。原因是 ETCD 提供的功能,和配置中心的需求重合性很高,天生就比较适合,自研起来工作量小,基本上,只需要开发个操作 ETCD 的配置的后台即可。我们把配置中心的六大需求一个个拉下来看:

  • 配置的集中化管理,统一标准。

配置存在 ETCD,因为 ETCD 没有专门的配置中心后台,需要自己实现一个,做出来增删改查和权限管控,就基本可以了。

  • 配置的安全存储,不丢失。

ETCD 作为 Kubernetes 的底层存储,安全性应该是很有保证了。

  • 下发配置到服务,并支持自动更新。

V3版本支持 基于 grpc 的 Watch 机制,性能和可用性都有保证,可以实时更新配置。

  • 敏感配置的加密,权限管控。

加密这块 ETCD 本身也不支持,需要开发。

  • 高可用,配置中心作为系统的关键节点,必须保证可用性。

支持多节点部署,作为云原生时代的基础设施,相关运维的经验也比较丰富,可用性有保证。

  • 接入成本低,一般来说,刚开始以业务为主,对配置文件的管理需求没那么着急,等业务稳定才会考虑建立配置中心。那么,如何快速接入,快速切换,就很重要了。

有各语言的 SDK,接入起来比较简单。

这里最难的就是高可用部署,如果自研,多节点数据一致性保证,包括后期的运维都是在重复造 ETCD 的轮子。配置中心本身的属性也决定了它不是被高频访问的应用,因此 ETCD 提供的并发能力完全已经足够了。

Sail

Sail 是一款开源的配置中心,它是我在开发了多款配置中心的基础上,总结经验,最后写出的一个开源项目,实际上,它的架构核心正是 ETCD:

sail-data-flow.pngsail-data-flow.png

它为 ETCD 提供了一个专业的配置中心管理界面,通过界面对配置进行增删改查,并且提供了sdk,简化接入 etcd 的步骤。从配置中心的六大能力块来看:

  • 配置的集中化管理,统一标准。

通过 Web 管理界面管理,支持配置层级划分、公共配置、权限管理、配置增删改查、多种类型的配置等各种功能。

  • 配置的安全存储,不丢失。

正如上面所说,基于 ETCD 的 Sail,无需开发数据安全、一致性保证等功能,ETCD 本身会提供。

  • 下发配置到服务,并支持自动更新。

封装 ETCD 的 SDK,提供更简单的接入。

  • 敏感配置的加密,权限管控。

源头上支持加密,ETCD 存储的就是加密信息。在 SDK 中解密。解密秘钥可以通过环境变量等方式传递,环境变量可以通过 Jenkins 等发布系统注入,全程秘钥可以不公开,运行时才解密,保证了配置的安全性。

  • 高可用,配置中心作为系统的关键节点,必须保证可用性。

可用性也是通过 ETCD 保证,ETCD 的部署节点越多,则越安全。但官方建议,不要超过 7 个。

  • 接入成本低,一般来说,刚开始以业务为主,对配置文件的管理需求没那么着急,等业务稳定才会考虑建立配置中心。那么,如何快速接入,快速切换,就很重要了。

提供 golang SDK ,go 项目接入起来无任何压力。其它语言项目,需要通过 ETCD 提供的语言相关客户端处理。

同时,Sail 还在全力开发 配置发布管理 和 监控指标输出 功能,这是 Sail 的最后两块拼图。

通过发布管理,可以控制自动更新时的策略,是按比例推送,还是先推指定节点等。

监控指标输出,则是对接 Prometheus,完善配置中心的可观察性。

总结

最后,引用那句经典的“软件开发里没有银弹”,我想补充一句:“你要知道你手里有哪些类型的子弹。”通过对比和分析,来确定当时,当地,最适合项目的那个方式,比如项目着急上线,先直接把配置文件写死在代码里,都不是不可以的,后期可以再改。如何做好一款配置中心?希望看完本文你能有自己的答案。

0 人点赞