前言

在我们日常的划水中,常常听到持续集成持续部署持续交付DevOps,那么这些名词到底是什么意思?对我们的日常工作有什么作用呢?能够提高划水的效率呢?其实对于名词的解释始终还是千人千面,不同环境下必然存在不同的产物,我今天想说一说我自己的理解,希望不会对你有误导。

什么是持续交付

持续交付:(英语:Continuous delivery,缩写为 CD),是一种软件工程手法,让软件产品的产出过程在一个短周期内完成,以保证软件可以稳定、持续的保持在随时可以释出的状况。它的目标在于让软件的建置、测试与释出变得更快以及更频繁。这种方式可以减少软件开发的成本与时间,减少风险。

由上可知,持续交付的关注点在于以下几个方面:

  • 短周期
  • 随时可释出
  • 频繁构建

持续交付也可以拆开分析,所谓持续便是一直的频繁的做某件事,有一种开始也是结束,结束也是新的开始的感觉,需要闭环反馈来支持下一个阶段的持续行为;而交付则表示针对当前交付目标释出可行的产物。上面提到的随时可释出频繁构建很好的体现了持续交付的行为特性,而短周期则是表示每一个阶段的交付过程应该在一个短的周期之内完成,因为短周期意味着快速交付、快速反馈、快速反应并快速的循环反复,而长周期必然会加大一次交付流程的耗时(加大试错成本,无法快速反应),所以这样才能够达到持续交付的目的(随时可交付)。至于什么才是合适的短周期,这个需要结合企业或团队的具体情况(比如项目当前所处阶段、研发人员素质、研发上线流程等)进行考虑。

说了这么多,那么持续交付是以什么样的形式。如何落地到我们日常的工作中的呢?结合美团外卖持续交付分享(美团外卖持续交付的前世今生)和极客时间课程持续交付36讲,我总结了如下的一种描述。(希望不会将你带偏)

关于持续交付,不同的企业、不同的团队站在不同的角度会存在不同的定义,我们可以把持续交付定义为一个产品价值的开发框架(站在企业的角度)、一套软件工程方法论以及许许多多最佳实践的集合。持续交付的落地便是开发框架或软件工程方法论与实际情况的结合的实践(也可以说是最佳实践的排列组合),更详细的实践情况还请接着往后看。

持续集成、持续部署、DevOps和持续交付的关系

持续集成

持续集成:(英语:Continuous integration,缩写CI),是一种软件工程流程,是将所有软件工程师的软件工作副本持续集成到共享主线(mainline)的一种举措。该名称最早由葛来迪.布区(Grady Booch)在他的布区方法中提出,在测试开发驱动(TDD)的实践中,通常还会搭配自动单元测试。持续集成的提出主要是为了解决软件进行系统集成时面临的各种问题,极限编程称这些问题为集成地狱(integration hell)。

持续集成的关注点在于:

  • 频繁集成
  • 有效协作
  • 自动化测试

我们通常会将软件研发工作拆解,拆分成不同模块或不同团队进行编码,编码完成后,进行集成构建和测试。这个从编码到构建再到测试的反复持续过程,就叫做持续集成。由持续集成的定义可联想到版本控制,如 Git,进而可以关联到分支策略(如:Git Flow、GitHub FLow、GitLab Flow),可以说分支策略是持续集成的前置条件。一般情况下,会有一个分支作为集成使用,加上多个特性分支(这里和具体的分支策略强相关,并不是所有团队的都是一样的),当特性分支开发完毕,通过 PR 请求合并到集成分支,此时会触发持续集成工作流程,保证待合并的分支内容是有效的,只有通过持续集成流程验证,才能合并到集成分支。

持续部署

持续部署:(英语:Continuous deployment,缩写为CD),是一种软件工程方法,意指在软件开发流程中,以自动化、频繁而且持续性的,将软件部署到生产环境(production environment)中,使软件产品能够快速的发展。持续部署可以被整合到持续集成与持续交付的流程之中。

持续部署的关注点在于:

  • 自动化的
  • 频繁的
  • 持续性
  • 生产环境

在一些企业的软件部署工作中,仍然存在全人工操作的方式。如果只是单纯的安装部署目的还较为容易(不过繁琐的配置,人工的不规范、不确定性,部署的耗时等都是成本);而如果是已上线的服务的部署工作(服务更新),此时的涉及面以及受影响的范围就比较大了。就算释出的产物已经可以达到可交付的标准,但是要使得用户真正可用,还需要跨越安全、快速以及稳定部署的障碍。那么是否可以将部署的场景和过程进行抽象,使用统一的、规范的、自动化的方法论和流程来约束和实现部署的过程。而持续部署便是这样的一套方法论及实践工具集,旨在规范部署行为,通过自动化提高部署效率,达到持续部署目的。

持续集成、持续部署与持续交付的关系

当提到持续交付的时候,总能关联到持续集成与持续部署,我也一直傻傻分不清这三者之间有什么区别,是什么样的关系。不过从前面给出的定义和关注点可以知道,持续集成侧重于编码阶段内多人协作产物集成的有效性,持续部署侧重于将产物部署到生产环境,而持续交付则侧重于需要随时可释出;而相同点在于他们三者都推崇持续性,即存在一个反馈的过程,且反馈的结果作为下一阶段持续的支持。

再说到持续集成、持续部署和持续交付之间的关系,这里还有一个比较有趣的地方,那就是在不同的视角下,三者的关系并不一样,这里借鉴美团外卖分享的内容(美团外卖持续交付的前世今生)举例,从研发和产品的角度来分析这三者的关系。

  • 研发视角:我们可以看到大部分研发团队,会从软件研发的角度进行定义,他们将软件的开发步骤拆解为持续集成、持续交付、持续部署,其中持续集成指开发人员从编码到构建的过程;持续交付则作为持续集成的自然延续,指将已经集成构建完成的代码,交给测试团队进行测试的过程;持续部署指将测试通过的软件交付给用户的过程。在研发的视角下,持续交付就是一个承上启下的过程,与持续集成形成了闭环,而又为将来达到持续部署做下了准备。此时持续集成 + 持续交付 + 持续部署便是一条完整的发布流水线。

  • 产品视角:产品团队会站在产品的角度来看,他们认为持续交付,是从需求的 PRD 文档提出来,到用户能够感受这个需求的周期。也就是说,此时持续交付是完整的包含了持续集成与持续部署,但是持续交付涵盖范围是大于持续集成 + 持续部署。并且,此时的持续交付流程本身就包含了一条完整的发布流水线。

借用持续交付36讲中的 发布流水线 示意图

发布流水线

说到这里已经不难看出,影响三者之间相互关系的因素主要在于对于持续交付的定位。在这里先说说我自己的看法,我认为持续交付的核心要义在于:短周期时刻可释出持续构建,即在于持续的产出与持续验证,由产出与验证形成闭环,进而相互推动,以达到快速反应,快速实现,持续优化。而短周期便是一次交付过程耗时的预定义,也是对于效率的要求,但一定不是对用人的压榨(去你xxx)。在持续交付中,交付对象不一定就是最终用户,所以千万不要认为一定要做到端到端完整才是持续交付。持续交付是一个周期性、可持续的行为,可以只是研发到测试的闭环,此时于研发而言交付对象是测试团队,交付物为通过持续集成验证的代码;也可以如产品视角一般,从需求的 PRD 提出来到用户能够感受到这个需求的周期,此时交付对象为用户,交付物为可用的产品。

所以持续交付可以只是一套方法论,可以是产品价值开发框架,也可以是一部分流程实践。于我个人而言,我更认同持续交付是一套方法论(兼产品价值开发框架),由此指导持续交付体系的建设。如果你问我持续交付体系实践中使用到的技术是不是持续交付,我会说,在其中使用到的技术或工具只是当前持续交付体系建设的一个组成部分。所以,关于持续集成、持续部署、持续交付三者之间的关系,我认同为:三者相互渗透(可能这个词不是很恰当),并没有绝对的独立。

DevOps

DevOps:(是 Development 和 Operations 的组合词),是一种重视“软件开发人员(Dev)”和“IT 运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。通过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。

传统的软件组织将开发、IT 运维和质量保障设为各自分离的部门,再这样的环境下如何采用的新的开发方法(例如敏捷软件开发),是一个重要的课题。按照从前的工作方式,开发和部署,不需要 IT 或者 QA 支持(跨部门的持之),而现在却需要极其紧密的多部门协作。而 DevOps 考虑的不仅仅是软件部署,它是一套针对这几个部门间沟通与协作问题的流程和方法。

以上关于 DevOps 的定义摘取子维基百科,我们可以从中提取到如下几个关注点:

  • 是一种文化
  • 是一种运动
  • 沟通协作
  • 自动化
  • 持续性
  • 频繁
  • 低风险、可靠

通过上述定义和简单分析,我们对 DevOps 有了一个基本的认识,但还不够了解,不足够在我们的脑海里构建一个与之对应的场景,下面我会借鉴极客时间课程 DevOps 实战笔记的描述和我自己的理解来加深理解。

提到 DevOps 是什么之前,我们可以先了解一下 DevOps 想要解决的问题究竟是个啥。由维基百科中给定的定义可知,DevOps 最初关注软件开发团队和IT运维团队之间的沟通协作问题。而谈到开发与运维的相爱相杀,又可以先说一下当前存在的开发模式:

  • 瀑布式开发模式:该模式将软件交付过程划分成几个阶段,从需求到开发、测试及运维。在软件开发的规模日益扩大时,通过分阶段、重流程、重规范、重管控来保证每一步都在计划之内,并以交付物作为每一个阶段的释出,只有达到交付标准才允许进入下一个阶段。这样的开发模式需要一开始就确定的知道项目的目标、范围以及实现方式,而现实中大部分时候处于了解的信息并不十分充足的阶段,如此情景下的决策总是缺少着完整数据的支持的。如果后续变化较多、较大,都会导致项目交付周期持续增长。

  • 敏捷式开发模式:瀑布式开发模式不适合需求不明确,时间周期较为紧张的场景,但是基本上很少有工程在一开始需求就是十分清晰且稳定的。基于这样的问题,敏捷的思路开始盛行。在我自一次听说敏捷开发的时候,我一直误认为使用了敏捷就能加速产出的速度,但其实这么说并不合适。敏捷的核心理念是,既然无法充分了解用户的真实需求,那么就拥抱变化吧,将一个大的目标拆解为一个个小的可交付的目标,然后不断迭代,以小步快跑的方式持续开发(分治思想,每一个小的迭代产生的变化是小的,带来的影响也是小的,可以平滑的进行生长)。与此同时,将测试工作注入到整个开发活动中,对开发交付的内容进行持验证,保证每次可交付的都是一个可用的功能集合,并且把质量把控内健在研发环节中,交付功能的质量也是有保障的。敏捷之所以敏捷,根本原因在于持续迭代和持续验证节省了大量不必要的浪费和返工。

  • DevOps模式

在瀑布模式中,开发、测试、发布是由三个各自独立的部门协作完成;到了敏捷式开发模式中,测试已经成功的被拉拢到了开发阶段中,剩下独自美丽的运维。但是,为了工作的效率,大家的快乐,只能想办法让所有人一块美丽。就是在这样的环境下,DevOps 应运而生。也就是说,DevOps 最开始想要做的,就是打破开发与运维之间的对立与隔阂。

通过上面的分析和描述,我们可以知道,DevOps 最初的用意只是打破开发和运维之间的隔阂,建立友好、互助、共赢的价值观。但是在经过一段时间的实践之后发现,在整个软件交付过程中,不仅仅只有开发和运维,还会有如业务团队、安全团队等。也就是说,需要拉拢的其他对象出现了。此刻,我们相继拉拢了业务团队和安全团队,DevOps 涵盖的团队有开发、运维、业务和安全,而且业务团队认为可以使用 BizDevSecOps 来代替 DevOps 的称谓了,因为 BizDevSecOps 才是业务团队眼中的 DevOps。那么到底什么才是 DevOps呢?是否能够给出一个明确的定义?在这里先给出极客时间课程 DevOps 实战笔记作者石雪峰老师的见解:DevOps 是通过平台(Platform)、流程(Process)和人(People)的有机整合,以C(协作)A(精益)M(度量)S(共享)文化为指引,旨在建立一种可以快速交付价值并且具有持续改进能力的现代化IT组织

突然想起了 GIS 的组成部分,请自动过滤这句废话。老话说得好,不以结婚为目的的谈恋爱都是耍流氓。而 DevOps 也应该先谈目的,我认为,DevOps 的目的就是实现快速、稳定、可持续优化的价值交付,任何阻挡其实现的障碍都会通过一些手段(不择手段的手段)将其优化掉(比如:自动化代替绝大部分人工,繁琐或不正确流程重定义、协作共赢的价值理念宣传/洗脑 等)。所以,我更倾向于认为 DevOps 就是指引如何实现其目的的一类文化,而可以快速交付价值并且具有持续改进能力的现代化IT组织便是达到目的手段的整合,也是 DevOps 的落地。

其实,DevOps 只是一个代号,甚至是不是叫做 DevOps 我认为并没有那么重要(也不太正确,如果名字没取好,可能就流行不起来了),比如对于安全团队来说,他们眼中的 DevOps 可能是 DevSecOps。但是我们知道,DevOps 代表这一种文化,当你心里想着如何才能更好地和前端(xx端)小哥哥小姐姐沟通以快速实现目标时,你就很“DevOps”了。

DevOps与持续交付的关系

从前面所有的描述里面可以很明显的看出,其实 DevOps 和持续交付想要达到的最终目的是一致的(快速、稳定的交付产物),但是相较于持续交付来说,DevOps 涵盖的范围更加的广阔。由给出的定义分析,我认为 DevOps 和 持续交付是一种包含关系, DevOps 包含了持续交付。本质而言,他们都是同一类理念、文化(高效、精益、持续)的不同实践,只不过 DevOps 关注的范围更大,视角更高,所以从同理念不同实践的层面上分析,DevOps 包含了持续交付。

持续交付有什么价值

都在讨论持续交付,那么持续交付能给我们带来什么样的价值呢?这个问题其实很好解答,或许不全面,但是能引起共鸣就好。

我们完全可以从自己所在的环境进行分析,就比如我所在的环境中,我这里基本上都是 To G 的项目,暂时没有形成自己的核心产品,所以都是以项目的形式从无到有的推进。我们采用的开发模式是瀑布式开发模式,发布部署的方式仍然还是完全人工的方式。通过对一个完整项目交付结束后的分析,在交付过程中我们主要存在以下几个方面的问题:

  • 需求的不确定性,朝令夕改(夸张的修辞手法),发布时间延迟
  • 瀑布开发模式下,测试介入比较晚,且不存在QA
  • 完全人工部署,一次部署总是会出现环境或配置上的问题,需要通过维护一份友好的部署文档来提高效率

而持续交付能够带来的是什么,通过变更开发模式使得拥抱变化、通过持续集成可以保证特性功能集成的有效性、将测试工作提前到开发阶段保证功能的稳定性、通过持续部署保证部署的正确性、通过快速交付迭代保证快速的响应,快速变化,降低试错成本,同时时刻为交付做好准备。

所以持续交付的价值在于:

  • 提高生产效率,支持快速响应
  • 规范化、标准化发布流程

为什么需要引入持续交付

这个问题看上去和“持续交付有什么价值”有一定的重叠,确实如此,在上一个问题中,我列出了我所在环境遇到的问题,也简单提到了持续交付能够带来的价值。之所以需要引入持续交付,是因为需要变化来驱动我当前环境进行改变,以达到提高研发效能的目的。

持续交付能带给我什么呢?

  • 执行编码标准、API设计标准等
  • 制定统一的、规范的发布流程
  • 持续集成保证每一次的集成中,代码是有效的
  • 提前接入的测试,可以保障每一次的交付迭代的质量稳定
  • 快速的迭代可以低成本的应对合理的需求变化
  • 持续部署可以去掉大量的人工操作,保证了部署的正确性,且规范了部署的行为(比如目录的定义,产物存储位置)

所以我需要引入持续部署。(其实上面提到 DevOps 和持续交付是同理论不同实践的产物,为什么我在这里引入的是持续交付而不是 DevOps呢?主要是因为我目前只想快速的进行实践,通过持续交付的方法论,结合持续交付工具集快速的搭建符合我所在环境的持续交付流程。我当然不会告诉你我先买了持续交付课程,看完了才买的DevOps课程,再说了该文讲的是持续交付好吧。俗话说得好,不管黑猫白猫,抓到老鼠就是好猫。DevOps    等我!)

总结

在这里,我结合多方资料对持续交付、继续继承、持续部署、DevOps 进行描述,并分析了他们之间的关系,希望不会给你带来误导(如果有你也别找我)。

其实,不论是持续交付、DevOps 还是 AIOps等等,本质上都是通过一定的手段达到提高效能、精益求精的目的,所以没有最好的,只有最合适的。

参考文献

说明

我不是在卖课

本文大部分内容来源于极客时间以及网络博文节选,如有冒犯,我先向您道歉,另还请告知我进行处理,谢谢
邮箱:thread_zhou@126.com