透明思考


Transparent Thoughts


技术栈管理与云时代的持续集成

在刚刚发布的第16期技术雷达中,我们看到ThoughtWorks在“技术”象限里旗帜鲜明地列举了几项与持续集成相关的反模式。这些存在多年的实践和现象被放在了“暂缓”一环中,意味着ThoughtWorks正式向我们的客户指出:如果你的组织仍在这样实施持续集成,我们认为你应该考虑改变了。那么,这些被批评的点背后映射出哪些问题,基于技术栈管理的云时代研发环境又能带来什么新的思路?我们一起来深入分析。

持续集成的反模式

最需要被点名批评的现象莫过于“持续集成剧场”了:

很多开发者只是简单的搭建了持续集成服务器就以为在做“持续集成”,但他们实际上会遗失持续集成的关键优点而导致失败。常见的失败模式包括:虽然在一个共享的主分支上运行持续集成,但是代码提交不频繁,所以集成并没有真正的“持续”。以及在一个测试覆盖率不足,甚至是长期状态为红的情况下进行构建;或者在功能分支上运行持续集成,这会导致持续隔离。

简而言之,这些团队并没有真正体会到持续集成的好处,而是为了完成上级的任务而演一场“我们在持续集成”的戏——这也正是这个反模式的名字由来。过去十年中,我们在众多刚开始实施持续集成的企业见过这一幕。领导认识到持续集成的好处,但是推行成了个大问题:推轻了,下面团队不愿动,技术问题解决不了;推重了,下面团队来个上有政策下有对策,领导想看什么就给你演什么——持续集成剧场就此落成。比如说你见过一个表面看起来一直是绿色但是背后连编译都不敢跑的持续集成吗?我见过。真是一场好戏。

为了解决持续集成演戏的问题,一些规模较大的企业开始建设持续集成中心。想法很符合直觉:既然团队自己做持续集成有技术困难、还有可能变成演戏,那么我就组建一支团队专门帮他们一个个把持续集成跑通、帮他们管理持续集成服务器,持续集成的运行和统计数据都在这个中央团队手里,下面的团队总没办法演戏了吧?于是,他们又遭遇了第二个持续集成反模式:“所有团队共用一个持续集成实例”。

那些必须使用中心化持续集成服务器的交付团队,常常依赖中心的团队去完成小的配置任务,或者在共享的基础设置和工具中排查问题,这给他们在进度上带来长时间的滞后。

这次是康威定律带来的困难:如果每个团队使用的技术栈配置不同、技术栈配置和管理的职责仍然在每个团队中,那么技术栈演进与持续集成的演进就难免出现节拍不一致。于是管理着持续集成中心的中央团队开始疲于奔命,帮一个个项目团队修持续集成,而项目团队还感到没有得到足够的支持。

第三个反模式是“企业级集成测试环境”,这也是很多组织建设持续集成中心的初衷之一:由于能执行完整端到端测试的环境稀缺,各个团队的集成测试无论如何也必须在一个瓶颈处统一调度,所以中心化管理持续集成也就顺理成章。然而,

这些企业集成测试环境通常称为 SIT 或预生产环境)是当下持续交付常见的瓶颈。环境本身很脆弱而且维护成本很高,而这些环境通常存在一些需要由单独的环境管理团队手动配置的组件。在预生产环境的测试给出的反馈慢且不可靠,而且会重复测试那些在隔离的组件上已经测过的功能。

云时代的新思考

技术雷达中批评的这些持续集成的反模式,是过去的时代背景造就的。尤其是以下几点约束条件,造成了今天我们看到的持续集成的形态(以及长久以来存在的挑战):

  1. 计算资源短缺。这个约束条件决定了完整的、与生产环境相似的、能执行端到端验证的环境必定是稀缺品,因此一个组织中多个团队的集成必定会受限于某个瓶颈,或是企业级集成测试环境、或是持续集成中心。
  2. 计算环境没有弹性。不仅硬件资源短缺,而且环境的开通、配置和管理很麻烦,所以团队会调整自己的技术实践去适应已有的环境,而这个调整的动作主要由团队内的技术领导者来执行。其结果是即便多个团队开发的软件在技术栈上非常相似,他们的持续集成实践也可能相当不同,在技术能力不足的团队就会变成持续集成剧场。
  3. 版本控制工具的局限性。Subversion(以及其他更早的版本控制工具)在pre-commit阶段通过服务器端回调钩子很难——如果不是完全不可能的话——得到完整的“提交后版本”,因此svn的pre-commit钩子基本只能用于检查提交信息是否符合规范,完整的验证则必须在代码已经合入代码库之后才能——在一台独立的“持续集成服务器”上——进行,而此时如果构建失败就会阻塞整个团队的工作。这也导致更多的团队倾向于放松持续集成的要求、甚至沦落成持续集成剧场。

而这几个约束条件在今天的时代背景下已经不复存在:计算资源仍然不能说极大丰富,但企业应用开发所需的x86架构计算资源在云环境下已经不再短缺;在IaaS的基础上,技术栈管理的PaaS提供了计算环境的弹性,使用相同技术栈的多个团队可以轻易地获得完全一样的环境,因此团队也可以采用标准的技术实践,而不必为了将就手边的环境而调整实践。而git对svn的全面取代尤为值得玩味:由于可以在pre-commit阶段直接获得完整的待提交快照、并在这个版本基础上执行测试,不符合持续集成要求的代码将直接被拒绝提交——而不是在提交后才把问题暴露出来。于是,以下两个要素的结合:

  1. 每个开发人员(以及自动构建)都可以在PaaS云上获得完整的技术栈运行时环境;以及,
  2. pre-commit阶段可以对待提交的代码进行完整的构建

将带来两个重要的影响。首先,持续集成不再需要一个“服务器”。从它发展的早期开始,持续集成这个概念就一直与各种“持续集成服务器”软件工具紧密关联:从早期的CruiseControl、Bamboo到后来的Jenkins、GoCD,以及云上提供服务的TravisCI、SnapCI,持续集成中的“集成”这个动作一直发生在代码已经提交之后、发生在一个团队共有的服务器上。而现在,持续集成可以在代码提交之前发生、在一个从PaaS云上弹性生成的环境中发生。

这个技术性的改变带来的组织性改变将有着重要的意义:保证持续集成通过将会彻底变成每个开发人员自己的责任,没有折扣可打,没有其他地方可以推卸责任——现在构建不通过不会阻碍其他人提交代码了,只有这个开发人员自己不能提交代码。由此,持续集成将由一项团队实践变成一项个人实践、由一项有较大妥协空间的实践变成一项强制性的实践。正如IntelliJ之类现代IDE把“通过编译”这项要求变成了程序员感知不到的、而又不可妥协的质量要求,技术栈管理PaaS平台将把持续集成也变成程序员感知不到的、而又不可妥协的质量要求。

持续集成是如此重要,以至于我们不应该把它交给程序员自己去做。

在这样的一个研发环境下,每个开发人员从写下第一行代码开始就必须遵循组织的质量规范,能够被提交到团队代码库的代码都是通过了验证流程、符合质量要求的。6年前当我构想这样一个研发环境,我觉得它更像是一个遥远的梦想。然而今天,支持这样研发环境的技术栈管理PaaS平台已经被实现出来了。你需要的就是在你的研发云上实施它。

(本文作者熊节是ThoughtWorks的总监咨询师)