@Rays
2017-07-10T08:55:11.000000Z
字数 3483
阅读 1583
持续集成
摘要: 本文介绍了MyHeritage的持续交付之旅,它实现了从耗费时间、令人痛苦的手工发布过程,向一种完全自动部署流水线的转变。
作者: Ran Levy
审校: Manuel Pais
正文:
本文要点
- 持续部署对业务、质量、速度和满意度有着重要的影响。
- 任何巨大的更改都开始于增量小步骤。
- 任何完全持续部署得以应用之前,都需要一些测量到位,其中最重要的就是测试。
- 持续部署是一个革命性过程,从“足够好的事情”开始,并一路改进。
- 手工脚本和任务是易于出错的(浪费的)和消耗时间的,因此应瞄准于实现整个流水线的自动化。
你可能会提出疑问:“这又是一篇持续部署的文章吗?”如果要让我回答“是”或“不是”。那么我可以回答“是”,因为该文的确是介绍持续部署(CD,Continuous Deployment)的;我也可以回答“不是”,因为文中将介绍我们在MyHeritage所实现的一种独特的CD过程,其中涵盖了测试、所有开发人员工作于同一分支(即主线Trunk)上,并且聊天机器人也构成了部署流水线的一部分,还有更多的内容。
多年前,MyHeritage的研发部门同时在多个分支上工作,其中部分是长期存活的分支。一旦某个特性接近于准备好的阶段,代码就会归并到主线上。但是这样的归并的确是一种梦魇般的经历,其中存在很多些冲突,并且要找出存在的问题,需耗费大量珍贵的研发时间。
我们在归并上所面对的麻烦远非如此。由于我们每周都要做部署,其中一些部署需要归并来自于不同分支的组件,这些组件在此之前从未一起工作过。它们被规划在一个“超大”的代码发行版(具有多个软件包)中发布。这样的服务包的发布过程是一个非常繁琐、易于出错并且令人感到沮丧的过程。
在与此类部署方式多次较劲后,我决定应启动向持续部署工作方式的转移。
对于一家服务于9千万用户、具有27亿条DNA树结构概要、77亿条历史记录和TB级敏感DNA数据的企业,要使企业转换到持续部署方式,必须要以增量小步伐完成。我们必须要确保工作方式的更改不会影响到站点的稳定性。
我们迈出的第一步是对新编写的后端和前端代码都添加单元测试。。但是单独这样做是不够的,因为依然无法覆盖已有的数百万行代码。我们决定要解决这些遗留代码,采取的方法是通过对重要组件编写集成测试和端到端测试(使用Cucumber)实现更广泛的覆盖。这些测试并没有单元测试那样有效,也更为缓慢。但是这些测试对于使用较少的开发工作实现更好的覆盖上具有很大的优势。很快,我们就达到了对代码块合理覆盖的程度。
图1 应用CD中的一个关键因素,是在多层次上实现测试。
我们已经形成对部分代码外部行为的控制能力,这主要是通过特性标识将特性暴露给用户实现的。该功能使用了基本的键存储值(出于高性能的考虑,采用了由Memcache支持的MySQL数据库),并可以控制出于测试目的以及真正对用户的特性暴露。为追踪更改的情况,对这些控制的全部更改都存储在一个审计表中。我们已经启动了金丝雀发布(通过暴露新代码给少部分用户而实现)、对生产环境的监控。在一切运行良好的情况下,我们会逐步增加特性暴露。
图2 特性标识系统和所触发的电子邮件通知。
与此同时,我们确保每个特性随监控生产环境中特性行为的统计信息和传感器一并发布(例如成功或失败次数、响应时间等)。我们瞄准采用秒为单位的最小可能采样时间,特别是可以监控生产环境中严重问题的关键传感器。联合详细的日志信息,我们能在生产环境中发生问题时进行快速的分析。
随着统计信息和日志消息数量的增加,我们采用了一些有助于我们了解生产环境状态的工具,例如NewRelic和ELK Stack。我们也开发了一些内部工具,简化了对日志信息和日志层级更改的理解和追踪(即如何从一个稳定状态发展到有问题的状态)。这些工具每日会对所有负责监控并修复自身责任范围内问题的开发人员发送两次报告。我们还开发了一个类似的工具,对我们所有的统计信息进行扫描,并报告其中所发现的任何异常。
图3 状态及日志自动扫描的电子邮件报告。
一旦所有的部署到位,我们就准备好开始“实验”。实验通过一小组开发人员以持续部署的方式构建一个新特性,即频繁的提交,不存在分支,并且由开发人员负责将代码发布到生产环境。
从发布至生产环境是一个手工过程,其中使用了发布服务包中所使用的同一脚本。这并非是一种更新生产环境的理想方式,但是我们的实验确实非常成功,并且有更多的敏捷团队逐渐地转换到这种工作方式。很快大家就抛弃了“打包服务”的方式。
我们已经认识到以持续部署方式工作的好处:
不断寻求提高的方法,是我们研发的价值观之一。很显然,下一步就是要改进手工发布代码到生产环境这一过程。
为此我们建立了一个敏捷团队,团队目标就是自动化CD流水线。我们想要避免耗费时间去手工运行脚本,这样的脚本必须由开发人员在特定时间手工调用。这种解决方案无法扩展,并且很浪费时间。
在完成一次Sprint之后,我们处于一种更好的状态。我们所具有的解决方案使得开发人员可以从IDE提交代码并触发构建,最终形成可供九千万用户使用的软件发布。
我们在后台开发了一个Jenkins工作流。该工作流在对主线的任何提交(即我们的单一分支)之后调用。作为工作流的组成部分,我们执行如下的步骤(其中一些是并行开展的):
图4 由许多易于监控的步骤所组成的CD流程图。
大家对这一“提交等同于部署”新过程的满意度非常高。它使得开发人员能在一个完全自动化的过程中,在25分钟内就将自身的代码从提交推送到生产环境。
我们在此期间学到了很多,并就如何进一步的改进收集了大量的反馈意见。其中包括:
图5 在CD Slack通道中提供的典型CD进展情况报告。
图6 在构建失败时给出的详细信息。
持续部署是改进我们的质量、速度和满意度的一个关键因素。企业在转换到持续部署方式工作前,需要实现一些里程碑工作。一旦企业已经着手做更改,这将使企业的研发部门乃至整个企业受益匪浅。
谨以本文献给那些我们研发部门中那些以持续集成方式工作的先行者,以及整个研发和DevOps部门。
Ran Levy是MyHeritage的研发副总裁,近六年来一直工作于MyHeritage。他具有20年的业界工作经验,曾在复杂大规模系统中历任开发人员、架构师和管理人员。Ran对敏捷和高效过程情有独钟,一直领导着公司向持续部署转换的过程。