分布式配置管理

问题描述

现在项目都在逐渐迁入docker集群,迁入后每个应用都会相互独立开,这样我们的服务器环境一下子从之前的二三十台虚拟机,变成了四五十个docker环境,再加上每个应用的docker容器可能会起来2-3个,那么一下子就有100+个docker容器(最终的docker容器应该比这个要多很多,因为定时任务、内部工具什么的还没考虑进来)。

我们的程序,往往依赖于外部接口,并且有很多定时任务脚本。这样每个容器都需要进行一些/etc/hosts文件和/etc/crontab的个性化配置,且这些配置是经常会发生变化的;另外我们的组件也会用到一些需要经常更新的数据文件(比如股票代码、行业、概念、交易日等等)。这些配置的管理如果全靠人工手动维护,会非常麻烦。

而这些配置管理,就是现在我们要解决的问题。

方案设计

客户端通过脚本定时轮询更新配置

这个就是目前我们的dbconfig的实现机制。有一个后台专门负责配置各项信息,然后每个客户端通过PHP定时脚本,每隔一分钟通过发送HTTP请求来后台获取数据文件,同步到本地。

这个方案有很多弊端:

1.文件更新不及时,受限于定时任务的执行频率

2.存在很多冗余的请求,可能有的文件一天都没变更,但是每分钟发一次请求,一天会有1440个无用的请求

3.单点故障,如果后台挂了,客户端的数据就没法更新了

客户端通过常驻进程来更新配置

这需要我们实现一个客户端程序,做到docker基础镜像中。

这个根据目前团队的技术栈,有很多种实现方案,可以用PHP、Java、Go、Python、Shell等来做。因为这个要做到基础镜像里面,所以使用的实现语言,其运行环境要尽量小才行。分析每种语言的运行环境:

PHP:需要安装PHP

Java:需要安装JRE

Go:需要安装环境

Python:系统自带,2.6版本

Shell:系统自带

考虑到这个客户端程序所处理的功能很简单,PHP、Java和Go都需要额外安装运行环境,Shell维护成本较高,没有明显优势,因此如果选择这个方案的话,可能用Python会是一个比较好的选择。

使用分布式开源工具

网上找了一下,发现了QConf这个360的开源工具,和我们的需求比较契合。

(Java也有一套方案:Spring Cloud Config,不过因为必须安装Java环境,有点浪费,因此没有考虑这个方案)

QConf有很多优秀的特性,其中最吸引我的是如下几点:

1.服务端通过zookeeper进行管理,没有单点问题

2.客户端将获取的配置,通过某个语言序列化,将序列化对象结果存储在共享内存中,直接供程序调用,性能非常好

3.我们这边的语言,都有对应的客户端支持

光有这个QConf还不行,我们仍然还需要自己写一个客户端程序,去做偏业务的功能,比如更新/etc/crontab和/etc/hosts文件。所以这个方案,其实是要和上面的第二个方案协同使用的。

总之:QConf解决配置问题,Java/Go/PHP/Python/Shell解决应用问题(hosts和crontab的更新问题)。

一些问题

Java在启动时就加载了数据文件,那么一旦数据文件发生变更,怎么通知Java进程重新加载数据?

待补充

基础镜像的大小问题

Java的SpringBoot基础镜像有513M,我装了PHP后,达到了1.33G!

推送到内网镜像仓库后,Java的SpringBoot基础镜像有202M,安装了PHP的镜像有465M.

参考资料

各种配置管理工具:https://zhuanlan.zhihu.com/p/36121392

QConf文档:https://github.com/Qihoo360/QConf/blob/master/README_ZH.md

MongoDB+QConf来解决配置问题:https://zhuanlan.zhihu.com/p/29530029

yum安装高版本gcc:https://blog.csdn.net/lanwilliam/article/details/77893033

通过scl安装升级linux的软件:https://www.linuxidc.com/Linux/2015-12/126662.htm