持续集成(Continuous Integration)与持续交付(Continuous Delivery )、持续部署(ContinuousDeployment)作为敏捷开发实践,可以及早发现、解决问题,从而更早地将产品交付给客户。及早地从客户那里得到反馈,就可以及早地对产品进行修复和完善,交付更加完美的产品给客户,最终形成了良好的可以持续的闭环。
持续集成是持续交付和持续部署的基础。持续集成使得整个开发团队保持一致,消除了集成所引起的问题的延期。虽然持续集成使得代码可以快速合并到主干中,但此时软件仍然是未在生成环境中进行实际使用过的。软件的功能是否正常,功能是否符合用户的需求,这在持续集成阶段仍然是未知的。只有将软件部署到了生成环境,交付给用户使用之后,才能检验出软件真正的价值。而持续交付与持续部署的实践,正是从持续集成到“最后一公里”的保障。
所谓交付,就是将最终的产品发布到线上环境,提供给用户使用。对于一个微服务架构系统来说,将一个应用拆分成多个独立的服务,每个服务都具有业务属性,并且能独立地被开发、测试、构建、部署。换言之,每个服务都是一个可交付的产品。那么在这种细粒度的情况下,如何有效保障每个服务的交付效率,快速实现其业务价值,是摆在微服务面前的一个难题。
而持续交付是一系列的开发实践方法,用来确保代码能够快速、安全地部署到产品环境中,它通过将每一次改动都提交到一个模拟产品环境中,使用严格的自动化测试,确保业务应用和服务能符合预期。因为使用完全的自动化过程来把每个变更自动提交到测试环境中,所以当业务开发完成时,你有信心只需要按一次按钮,就能将应用安全地部署到生产环境中。
而持续部署是持续交付的更高一级的阶段。即当所有代码所有的改动都通过了自动化测试之后,都能够自动地部署到生产环境里。持续发布与持续部署一个重要的差别在于,持续发布需要人工来将应用部署到生成环境中(即部署前,应用需要人工来校验一遍),而持续部署则是所有的流程都是自动化的,包括部署到生产环境的流程。图11-1很好地描述了持续发布与持续部署之间的差异。
让我们来探讨下一个完整软件的交付过程。假设现在需求已经明确,并且已经被划分为小的单元模块,如划分成用户故事,让我们观察下从开发人员拿到用户故事,到这些用户故事被实际部署到生产环境上的这个过程。对于这个过程来说,实际上时间越短越好,特别是对于那些急需获得用户反馈的敏捷开发方式的软件产品。如果我们做的每一个用户故事,甚至是每一次代码的提交,都能够被自动地部署到生产环境中去,那么这种频繁近乎持续的部署,对于很多敏捷软件开发团队来说,就成了非常值得追求的目标了。
当然实施持续部署并非没有投入和成本,如果产品的基础和特点不同,那么获得这种状态所需要的投入就越大。对于那些缺乏自动化测试覆盖的遗留系统,以及对安全性要求特别高的产品,它们要实现持续部署,甚至是频繁部署,都需要巨大的投入。但是如果产品所处的市场环境要求它必须能够及时做出相应的变化,不断改进软件服务的话,那么这种持续部署的能力就成了值得投入的目标。
持续部署,依赖于整个团队对所写代码的自信。这种自信,不仅是开发人员对自己写的代码的自信,更多的是团队或组织所有成员都抱有的基于客观事实的自信。只有建立起这种自信,才能够让任何新的修改都能够迅速地、有信心地部署到生产环境中。
在自信的基础上,团队要实现产品的持续部署,还需要建立自动化交付流水线(Pipeline)。
以自动化生产线进行对比,自动化测试只是其中一道质量保证的工序,而要将产品从需求转变为最终交付给客户的产品,自动化生产线是整个开发过程中极其重要的存在。特别是对于微服务这种多服务的产品而言,多个服务产品往往要集成在一起,才能为客户提供完整的服务。多个产品的自动化交付流水线的设计也就成了一个很重要的问题。
产品在从需求到部署的过程中,会经历若干种不同的环境,如QA环境、各种自动化测试运行环境、生产环境等。这些环境的搭建、配置、管理,产品在不同环境中的具体部署,都需要完善的工具支持。缺乏这些工具,生产流水线就不可能做到完全自动化和高效。与之配套的软件有Team-City、Jenkins、GoCD等。
总的来说,持续交付与持续部署在敏捷开发过程中,实现速度、效率、质量的软件开发实践,可以持续为用户交付可用的软件产品。其中包括:
需求分析、产品的用户体验和交互设计、开发、测试、运维等角色密切协作,相比于传统的瀑布式软件团队,减少了浪费。
有力形成了“需求→开发→集成→测试→部署”的可持续的反馈闭环。
在持续交付中,持续集成服务器将把开发到部署过程中的各个环节衔接起来,组成一个自动化的持续交付流水线,作为整个交付过程的协调中枢。依靠持续集成服务器,对软件的修改能够快速地、自动化地经过测试和验证,最后部署到生产环境中去。在自动化测试和环境都具备的情况下,集成服务器可以减少开发人员大部分的手工工作。流水线应向团队提供反馈,对每个人所参与的错误操作进行提示。
典型的持续交付流水线中,大致会经历构建自动化和持续集成、测试自动化和部署自动化等阶段。
1.自动化构建和持续集成
开发人员将实现的新功能集成到中央代码库中,并以此为基础进行持续的构建和单元测试。这是最直接的反馈循环,持续交付流水线会通知开发团队他们的应用程序代码的健康情况。
2.自动化测试
在这个阶段,新版本的应用程序将经过严格测试,以确保它满足所有期望的系统质量。这包括软件的所有相关方面,包括功能、安全性、性能等,这些都会由流水线来进行验证。该阶段可以涉及不同类型的自动或手动活动。
3.自动化部署
每次将应用程序安装在测试环境前都需要重新部署,但自动化部署最为关键的是自动化部署的时机。由于前面的阶段已经验证了系统的整体质量,这是一个低风险的步骤。部署可以分阶段进行,新版本最初可以先发布到生产环境的子集中,并在进行完整测试之后,推广到所有生产环境中。这极大降低了新版本发布的风险。部署是自动的,这样只需要花费几分钟就能向用户提供可靠的新功能。
下面总结了在构建持续交付流水线时一些好的实践经验。
1.做好配置管理
持续交付流水线需要有平台配置和系统配置的支持,这样就能允许团队自动或手动按下按钮来创建、维护和拆除一个完整的环境。
自动平台配置可确保您的候选应用程序能够部署到正确配置的且可重现的环境中去,然后进行测试。它还促进了横向扩展性,并允许企业在沙箱环境中随时尝试新产品。
2.合理编排流水线
持续交付流水线中的多个阶段涉及不同的人员团队协作,并且所有人员都需要监测新版本的应用程序的发布。持续交付流水线的编排提供了整个流水线的顶层视图,允许您自行定义和控制每个阶段的具体动作,这样就能细化整个软件交付过程。
3.不要添加新的功能,直到通过质量测试
持续交付使您的组织能够一个接一个地快速可靠地将新功能带入生产环境中。这意味着每个单独的功能需要在展开之前进行测试,确保该功能满足整个系统的质量要求。
在传统开发环境中,开发团队通常试图一次性实现一个完整的新版本,仅在项目接近完成时来解决软件质量属性(如鲁棒性、可扩展性、可维护性等)。然而,随着最终工期的临近,以及迫于
预算的压力,质量往往会首先被舍弃。
可以通过在获得质量权之前不添加新功能的原则来避免不良的系统质量。在实践中,您应该始
终首先满足并保持质量水平,然后才考虑逐步向系统添加功能。使用持续交付,每个新功能都需要
从一开始就满足整个系统所期望的质量水平。只有在达到此质量水平后,才能将该功能移至生产
环境。
1.什么是配置管理
配置管理是指一个过程,通过该过程,将所有与项目相关的产物,以及它们之间的关系都被唯一定义、修改、存储和检索。这里的项目相关的产物可以是源代码、需求文档、设计文档、测试文档等,也包括了项目配置、库文件、发布包、编译工具等。
配置管理是软件开发过程中极其重要的一部分,持续集成、部署流水线、自动化测试等若想真正发挥好作用,都必须做好配置管理工作。
2.如何进行配置管理
《持续交付》一书对配置管理做了重要的论述,并通过版本控制、依赖管理、软件配置管理和环境管理四部分来分别分析了配置管理的重要性。以下是所总结的配置管理的实践经验。
*应用程序所采用的各种操作系统或中间件,包括其版本、补丁级别及配置设置;
*应用程序所依赖的需要安装到环境中的软件包,以及这些软件包的具体版本和配置;
*应用程序正常工作所必需的网络拓扑结构;
*应用程序所依赖的所有外部服务,以及这些服务的版本和配置信息。
本书后续章节,也会探讨微服务的集中化配置的问题。
对于交付成功的软件来说,开发和运维是两个必不可少的过程。在传统的组织架构中,开发团队和运维团队往往是分属于不同的部门,各自部门的职责可能会引人相互抵触的目标:对于开发人员来说,开发人员的职责是负责交付新特性及对变更承担责任;而运维人员则试图保持所有功能能够平稳运行,对他们来说,避免变更正是降低运行风险的一种最有力的手段。在这种互相冲突的目标面前,最终导致产品不能得到很好的更新,也就无法持续给用户创造价值。
DevOps 正是为了打破开发团队与运维团队之间的壁垒而进行的一次尝试。DevOps是Develop-ment与Operations的缩写,DevOps推动了一套用于思考沟通和协作的过程和方法,用于促进开发、技术运营和质保部门之间的沟通、协作与整合,其推崇的团队将会是一个结合开发、质量保证( QA)、IT运营等整个职责的跨职能团队,如图11-2所示。这也正是Amazon所提倡的“You Build It,YouRun It(谁开发,谁运维)”的开发模式。
持续交付和 DevOps在其意义上及目标上是相似的(旨在快速交付产品),但它们是两个不同的概念。
DevOps有更广泛的范围,围绕:组织变革,具体来说,支持参与软件交付的各类人员之间的更大的协作,包括开发、运营、质保、管理等;自动化软件交付过程。
持续交付是一种自动化交付软件的方法,并且侧重于:结合不同的过程,包括开发、集成、测试、部署等;更快,更频繁地执行上述过程。
DevOps和持续交付有共同的最终目标,它们经常被联合使用,并且在敏捷方法和精益思想中有着共同的远景:小而快的变化,以最终客户的价值为重点。它们在内部进行良好的沟通和协作,从而实现快速交付产品,降低风险。
在微服务架构系统的开发中,我们倾向于采用DevOps的方式来组建全能型的团队。