背景

他姥爷又来了,他姥爷又忍不住寂寞打算码字了。 今天他姥爷想聊聊环境的问题。因为这里面有很多的坑,环境管理的好能让生产力翻倍,管理不好会团队痛苦不堪。这个是我的感受。记得也就 3 个月前吧,项目刚启动。开发,测试,产品都在使用同一套环境。是每个模块的开发人员出一个人临时糊出来的环境。我们有个习惯就是每个迭代结束后都开一个总结会,记得那时候大家抱怨最多的就是环境了。这么多人公用一套环境,难免互相影响,一会这个服务要重启,一会那个服务因为哪个 bug 挂了。再搭建几套环境也不现实,系统太复杂了,暂时没人能独立搭出来,维护的成本也太高。反正那时候大家都挺痛苦的。正好那时候基本没开发出什么功能,我还比较闲。而且本来我就在研究 CI 的方案,正好涉及到环境部署的问题。于是就想换个思路,以前做自动化部署大多是给测试人员服务的,这次给所有人定制环境。让每人都人手一套自己的环境。于是就这么干下去了。

准备工作

万事开头难,整合所有模块的部署细节往往是苦难的。因为这时候还没有配置管理,所有配置都是散落在各个不同的目录里。而且可能会变化。反正这时候就克服一下,以后有了配置管理方案就好了。

技术选型

谈到环境,首先想到的就是自动化管理。我们之所以只占用一个 QA 很少部分的时间就支撑起 20 多套产品环境,依靠的就是高度自动化。一般自动化部署要么就是传统的脚本驱动模式,要么就是虚拟化技术。我选择了 docker,有多方面的原因吧:

成型的结构图


画的不好大家见谅。每一个模块都是一个容器,每套环境都有独立的数据库,共用一个 hadoop 集群和 config server。但是有一个容器装了单机版的集群做备用,以防万一。记得第一次启用的时候,一下子开了 13 套环境(这个数字还真不吉利。。。),到现在将近 30 套。基本做到了人手一套环境。其中细节不表了,有兴趣的学习一下 docker 吧。总之多语言构成的产品比较麻烦,每种语言在部署的时候都或多或少的有些问题

开发环境定制

一开始就说了,环境不仅是给测试人员用,还要给开发人员用。于是就需要定制一些东西满足开发人员的要求。为了满足开发人员的需求就必然跟传统 CI 中的环境部署冲突。传统的测试环境部署方式一般是下面这样的:

这样的部署方式有一个问题,环境中可能只有一个部署的 jar 包。也许这对测试人员来说足够了,能看 log 就行。 但对于开发人员来说就有诸多不便。我们发现开发人员很喜欢在环境中直接编译源文件做开发。有时候可能 fix 一个 bug 很简单,直接在环境中编译一下重新启动服务就试一下了。 这比写代码,push,merge,重新拉取代码,重新部署要快速简便的多。我们开发人员大多都用 idea,大多都配置了 remote debug。所以只有一个 jar 包肯定是不行的。我们要在环境中保持一个完整的开发环境,例如完成的项目的 git 目录,git client,ssh,mysql client,local 编码设置等等等等。同时要有很方便的方式重启服务,不能让开发人员在重启服务的时候那么麻烦的走重新启动容器,拉取代码等等这一套流程。那么解决方案是:

测试环境定制

测试环境跟开发环境又有一点不一样。 我们在测试环境中最怕的是什么? 部署一个环境的时候发现连冒烟测试都过不去。bug 直接 block 测试流程,这时候只能等着开发修好 bug 再重新部署了。这很影响效率。 对于产品人员呢? 也一样的,产品人员有时候要跟老大,要跟客户演示,因为客户可能会来公司的。产品人员要演示最新的功能。但最新的功能可能还没有发布。需要在公司内找个环境演示。 所以不论是测试人员还是产品人员,都有一个稳定环境的需求。但其实我们避免不了 bug 的,我们部署一次环境的时候难免当时就有什么严重的 bug。解决方案一般有两个,一个是把以前的部署的包做备份。另一个是学运维在线上的策略 -- 蓝绿部署。 我选择了后者,所以测试环境的结构就变成了下面这个样子:

两套环境共用一个数据库和集群。 开发人员在提测的时候部署在 stable1, 下一次部署的时候我们就部署在 stable2。如果 stable2 是有问题的,例如冒烟测试没过。那么就切换回 stable1 测试。stable2 就打回去让开发修 bug。如此循环往复。我们保证始终有一套环境是可用的。

线上部署的定制

通过刚才的介绍我们发现我们是没有编译服务器的,我们在各自的容器里自行编译。这时候运维的同学就比较蛋疼。因为他们需要部署包来在线上或者进场进行部署。而我们的产品是比较复杂的,多语言构成的产品。让运维同学再搞一套编译服务器来生产部署包的成本也比较高。所以我跟运维的小伙伴商量了一下,还是复用我们现有的东西。其实就是我们新加了一个脚本。在已启动的经过测试的容器中把部署包 copy 出来。也就是说,我们的环境被当成了编译服务器

配置管理

这个东西单独拿出来说是因为它比较重要,我们在没有配置管理方案之前,部署是很痛苦的。因为配置文件散落在各个地方,掌握这些信息的成本太高,而且十分不利于扩展。增加或者修改配置的结果往往都是要更改 docker 的镜像并让所有人重新部署环境。所以大家在做环境管理的时候,一定要先推配置管理方案。否则你会痛苦死。这是血淋淋的教训。

总结

暂时就分享到这吧,其实我们做的还有很多不足,毕竟我们的项目才成立了几个月,好多东西不完善。现在 docker 的容器都是跑在一个机器里。之后一旦环境多了,肯定把 docker 做成集群。还有一些镜像的减肥,脚本的优化,环境自检的机制等等都需要完善。这里就当抛砖引玉了。大家晚安,俺陪媳妇睡觉去了


↙↙↙阅读原文可查看相关链接,并与作者交流