持续交付:发布可靠软件的系统方法
上QQ阅读APP看书,第一时间看更新

前言

引言

昨天,老板让你给客户演示一下产品很好的新特性,但你却什么都演示不了。所有新功能都只开发了一半,没人能让这个系统运行起来。你能拿到代码,可以编译,所有的单元测试在持续集成服务器上都能跑过,但是还要花几天才能把这个新版本发布到对外公开的UAT环境中。这种临时安排的商务演示活动算不上不合理吧?

在生产环境中发现了一个严重缺陷,它每天都在让你的公司蒙受损失。你也知道怎么修复它:只要在这个三层架构的系统中,修改那个被这三层都用到的库上的一行代码,然后再修改一下数据库中对应的表即可。但是,上次发布新版本到生产环境时,你花掉了整个周末的时间,而且直到凌晨三点才完活儿。另外,上次执行部署的那个家伙在不久之后因厌倦这样的工作辞职了。你清楚地知道,下次发布肯定不是一个周末就能搞定的。也就是说,该系统在工作日也会停机一段时间。唉,要是业务人员也能理解我们的问题就好了。

虽然这些事都很常见,但这些问题并不是软件开发过程不可避免的产物,它们只是在暗示我们:某个地方做错了。软件发布应该是一个快速且可重复的过程。现在,很多公司都会在一天内发布很多次。甚至对于那些代码非常复杂的代码库来说,这样做也是可能的。我们在本书中就会告诉你如何做到这一点。

Poppendieck夫妇(Mary和Tom)问道:“在你的公司里,仅涉及一行代码的改动需要花多长时间才能部署上线?你的处理方式是否可重复且可靠呢?”Implementing Lean Software Development第59页。从“决定做某种修改”到“该修改结果正式上线”的这段时间称为周期时间(cycle time)。对任何项目而言,它都是一个极为重要的度量标准。

在很多组织中,周期时间的度量单位是周或者月,而且发布过程也是不可重复或不可靠的。部署常常是手工操作过程,甚至将软件部署到测试环境或试运行环境都需要一个团队来完成,更不用说部署到生产环境了。我们遇到过同样复杂的项目,它们曾经也是这种状态,但是经过深入的业务流程重组后,对于某一关键的修改,团队做到了小时级别甚至分钟级别的发布。之所以能做到,就是因为我们创建了一个完全自动化、可重复且可靠的过程,让变更顺利地经过构建、部署、测试和发布过程。在这里,自动化是关键,它让开发人员、测试人员和运营人员能够通过一键式操作完成软件创建和部署过程中的所有常见任务。

本书将讲述如何缩短从想法到商业价值实现的时间,并使之更安全,从而彻底改变软件交付方式。

软件交到用户手上之后才会为个人或公司带来收入。这是显而易见的事,但在大多数组织中,将软件发布到生产环境的过程是一种手工密集型的、易出错且高风险的过程。虽然几个月的周期时间很常见,但很多公司的情况会更糟糕:发布周期会超过一年。对于大公司,从一个想法到用代码实现它的时间每延迟一周就意味着多出数百万美元的机会成本,而且这些大公司每次发布所经历的时间往往也是最长的。

尽管如此,现代大多数的软件开发项目仍旧没有把低风险软件交付的机制和过程作为其组成部分。

我们的目标是改变软件交付方式,将其由开发人员的手工操作变成一种可靠、可预期、可视化的过程并在很大程度上实现了自动化的流程,而且它要具备易于理解与风险可量化的特点。使用本书所描述的方法,就有可能在几分钟或几个小时内把一个想法变成可交付到生产环境中的工作代码,而且同时还能提高交付软件的质量。

交付成功软件的成本绝大部分都是在首次发布后产生的。这些成本包括技术支持、维护、增加新功能和修复缺陷的成本。通过迭代方式交付的软件更是如此,因为首次发布只会包含能给用户提供价值的最小功能集合。因此本书的书名《持续交付》就来源于敏捷宣言的第一原则:“我们的首要任务是尽早持续交付有价值的软件并让客户满意。”[bibNp0]这也反映了这样一个现实:对于成功的软件,首次发布只是交付过程的开始。

书中描述的所有技术都与交付软件新版本给客户相关,旨在减少时间和降低风险。这些技术的核心是增加反馈,改进负责交付的开发、测试和运维人员之间的协作。这些技术能确保当需要修改应用程序(也许是修复缺陷,也许是开发新功能)时,从修改代码到正式部署上线之间的时间尽可能短,尽早发现缺陷以便快速修复,并更好地了解与本次修改相关的风险。

读者对象及本书内容

本书的一个主要目标是改善负责软件交付的相关人员之间的协作,尤其是开发人员、测试人员、系统和数据库管理员以及经理。

本书内容广泛,包括经常提到的配置管理、源代码控制、发布计划、审计、符合性和集成,以及构建、测试和部署流程的自动化。我们也会讲述自动化验收测试、依赖管理、数据库迁移,以及测试和生产环境的创建与管理等技术。

参与过软件开发的很多人认为与写代码相比,这些活动不那么重要。然而,根据我们的经验,它们会消耗大量的时间和精力,而且是成功交付软件的关键因素。当与这些活动相关的风险管理没有做到位时,它们就可能耗费很多资金,甚至经常会超过构建软件本身的成本。本书会告诉你如何了解这些风险,而且更重要的是,会教会你如何降低这些风险。

这个目标很大,我们当然无法在一本书中面面俱到。事实上,我们很有可能会疏远各类目标受众,比如由于没有深入讨论架构、行为驱动的开发和重构等问题而疏远开发人员,或由于没花足够多的篇幅讨论探索性测试和测试管理策略而疏远测试人员,或由于没有特别关注容量计划、数据库迁移和生产环境监控等问题而疏远运维人员。

然而,市面上已经有一些分别详细讨论这些内容的书了。我们认为,真正缺少的是一本讨论如何把各方面(包括配置管理、自动化测试、持续集成和部署、数据管理、环境管理以及发布管理)融合在一起的书。精益软件开发运动告诉我们很多事情,其中有一件就是“整体优化是非常重要的”。为了做到整体优化,用一种整体方法将交付过程中各个方面以及参与该过程的所有人联系在一起是非常必要的。只有当能够控制每一次从引入变更到发布的整个过程时,你才能开始优化和改进软件交付的速度和质量。

我们的目标是提供一个整体方案,并给出这个方案涉及的各种原则。我们会告诉你如何在自己的项目中使用这些实践。我们认为不会有一种一刀切的解决方案可以应对软件开发中的各个方面,更不用说像配置管理和企业系统的运维控制这么大的主题了。然而本书所述的基本内容是可以广泛应用于各种软件项目的,包括大的、小的、高技术要求或短平快的快速收益项目。

在开始实际应用这些原则时你会发现,针对特定场景还需要关于这些方面的更详细信息。本书最后列有一份参考书目,以及一些在线资源链接,你可以在其中找到关于本书中各主题的更详细信息。

本书由三部分组成。第一部分阐述了持续交付背后的一些原则,以及支持这些原则所需的实践。第二部分是本书的核心——我们称为部署流水线(deployment pipeline)的一种模式。第三部分更详细地介绍了支持部署流水线的生态系统,包括:让增量开发成为可能的技术;高级版本控制模式;基础设施、环境和数据的管理;治理(governance)。

其中很多技术看上去只适用于大型软件应用。尽管我们的经验多数来自于大型软件应用,但相信即便是极小的项目也可以从这些技术中受益,理由很简单,项目会变大的。当小项目开始时,你的决定会对其发展产生不可避免的影响,以正确的方式开始,你会使自己或者后继者在前进的路上减少很多痛苦。

本书作者都认同精益和迭代软件开发理论,即我们的目标是向客户快速并迭代地交付有价值且可工作的软件,并持续不断地从交付流程中消除浪费。我们描述的很多原则与技术最早都是在大型敏捷软件项目中总结出来的。然而,本书中提到的技术都是通用的。我们的关注点更多的是通过更好的可视化和更快的反馈改善协作。这在每个项目中都会产生积极影响,无论项目是否使用迭代开发过程。

我们尽量做到每一章(甚至每一节)都相对独立,可以分开阅读。至少,我们希望你想了解的内容以及相关的进一步的参考信息是清晰且容易找到的,以便你可以把这本书当做一本工具书来用。

还要说明的一点是,我们并不追求所讨论主题的学术性。市面上与之相关的理论书籍非常丰富,其中很多都非常有趣,也不乏深刻的见解。尤其是,我们不会花太多时间在标准上,而是会关注那些对软件开发中的每个角色都很有用且经过实战检验的技能和技术,并尽量言简意赅地阐明它们,使其在现实中每天都能发挥作用。在适当之处,我们还会提供一些案例,以方便阐述这些技术。

内容简介

我们知道,并不是每个人都想从头到尾读完这本书。所以本书采用了特别的编写方式,使你一旦看过了介绍,就可以从不同的地方开始阅读它。为此,书中会有一定量的重复内容,但是希望不至于让逐页阅读的读者感到啰嗦。

本书包括三部分。第一部分从第1章到第4章,讲述有规律、可重复、低风险发布的基本原则和与其相关的实践。第二部分从第5章到第10章,讲述部署流水线。从第11章开始,我们会深入分析支撑持续交付的生态系统。

建议第1章必读。我们相信,那些刚接触软件开发流程的人,甚至是有经验的开发人员,都会从中发现很多挑战其对专业软件开发原有观点的内容。对于本书的其他部分,你可以在闲暇时翻看,或者在遇到问题时查看。

第一部分——基础篇

第一部分描述了理解部署流水线的前提条件。每章的内容都建立在上一章的基础之上。

第1章首先描述了在很多软件开发团队中常见的反模式,然后阐述了我们的目标以及实现方式。最后总结了软件交付的一些原则,本书的其他内容都以这些原则为基础。

第2章阐述了管理构建、部署、测试和发布应用程序所需的一些要素,包括源代码、构建脚本,以及环境和应用程序配置。

第3章讲述了在程序每个变更后执行构建和运行自动化测试相关的实践,以便确保你的软件一直处于可工作状态。

第4章介绍了每个项目中的各种手工和自动化测试,并讨论了如何确定适合自己项目的策略。

第二部分——部署流水线

本书的第二部分详细介绍了部署流水线,包括如何实现部署流水线中的各种阶段。

第5章介绍了一种模式,即本书的核心——每次代码修改后从提交到发布的一个自动化过程。我们也讨论了如何在团队级别和组织级别实现流水线。

第6章讨论了用于创建自动化构建和部署流程的脚本化技术,以及使用这些脚本的最佳实践。

第7章讨论了部署流水线中的第一个阶段,即任何一次提交都应该触发的自动化过程。我们还讨论了如何创建一个快速、高效的提交测试套件。

第8章展现了从分析一直到实现的自动化验收测试。我们讨论了为什么对于持续交付来说验收测试非常关键,以及如何创建一个成本合理的高效验收测试套件,来保护应用程序中那些有价值的功能。

第9章讨论了非功能需求,并重点介绍了容量测试,内容包括如何创建容量测试,以及如何准备容量测试环境。

第10章讲述自动化测试之后应做什么:一键式将候选发布版本部署到手工测试环境、用户验收测试环境、试运行环境,直至最终发布。其中包括一些至关重要的主题,如持续部署、回滚以及零停机发布。

第三部分——交付生态圈

本书的最后一部分讨论了用于支撑部署流水线的各类交叉实践与技术。

第11章的内容包括环境的自动化创建、管理和监控,包括虚拟化技术和云计算的使用。

第12章讨论了在应用程序的生命周期中,如何创建和迁移测试数据和生产数据。

第13章首先讨论了如何在不使用分支的情况下让应用程序一直处于可发布状态。然后描述了如何将应用程序分解成多个组件,以及如何建立和测试这些组件。

第14章概述了最流行的一些工具,以及使用版本控制的不同模式。

第15章的内容是风险管理和符合度,并提出了配置和发布管理的一个成熟度模型。然后,我们讨论了持续交付带来的商业价值,和迭代增量交付项目的生命周期。

本书中的在线链接

由于外部网站的完整链接很长,所以我们用了短链接,其格式如 [bibNp0]。有两种方法打开这个链接,可以使用bit.ly(其URL是http://bit.ly/bibNp0),也可以使用我们安装在http://continuousdelivery.com/go/上的一个短链接服务(Key值是一样的,所以上例中的URL是http://continuousdelivery.com/go/bibNp0),如果bit.ly因为某种原因停止了服务,你还可以用这个链接。如果网页更换了地址,我们会尽量保留http://continuousdelivery. com/go/这个短链接服务,所以如果bit.ly不可用,可以试一试这个。

关于封面的插图

Martin Fowler签名系列的所有书中,其封面都以“桥”为主题。我们原打算使用“英国大铁桥”的照片,但是它已经用在了本系列的另一本书上。所以,我们选择了英国的另一座大桥“福斯铁路桥”,这张美丽的照片由Stewart Hardy拍摄而成。

福斯铁路桥是英国第一座使用钢铁建造的大桥。其钢铁使用最新的西门子-马丁平炉工艺制造,并由在苏格兰的两个钢铁厂和威尔士的一个钢铁厂交付。钢铁是以管状桁架的形式运送的,这是英国首次使用大规模生产的零部件组装桥梁。与早期的桥梁不同,设计师John Fowler爵士,Benjamin Baker爵士和Allan Stewart计算了建筑压发生率,以便减少后续的维护成本,并计算了风压和温度对结构的影响,而这很像软件开发中的功能需求和非功能需求。他们还监督了桥梁建设,以确保这些要求都能得到满足。

当时有4600名工人参与建造该桥,其中不幸死亡约一百人,致残数百人。然而它仍是工业革命的一个奇迹,因为1890年建成时,它是世界上最长的桥,而到了21世纪初,它仍是世界第二长的悬臂大桥。就像长生命周期的软件项目一样,这座桥需要持续维护。这已在设计时考虑到了,大桥配套工程中不但有一个维护车间和场地,而且在Dalmeny车站还有一个50个房间的铁路“聚居点”。据估计,该桥的使用寿命还有一百多年。

版本记录

本书直接利用DocBookDocBook 是一种 XML(和 SGML)应用程序,可用于编写技术图书和文档,一度成为最流行的 XML格式。它非常适合于编写关于计算机硬件和软件的书籍和论文,但绝不限于这些应用。——译者注写完。David使用了TextMate编辑器,而Jez使用了Aquamacs Emacs。图形是用OmniGraffle画的。David和Jez通常身居地球的不同地方,他们之间的协作是通过Subversion完成的。我们还使用了持续集成技术,工具是CruiseControl.rb,每次有人提交一个更改后,它就会运行dblatex产生本书的PDF。

本书印刷前一个月,Dmitry Kirsanov和Alina Kirsanova开始排版制作,与作者的合作都通过Subversion库、电子邮件和共享的Google Docs表进行协调。Dmitry用XEmacs做DocBook源文件的修编,Alina则完成了其他事情,包括使用定制的XSLT样式表和一个XSL-FO格式化工具进行页面排版,从源文件中的索引标签里编译并编辑索引,并做了本书的最终校订。