乔梁:实施 DevOps 过程中的两个关键思考

2018-12-24 13:30:05 浏览数 (1)

《持续交付》译者《持续交付 2.0》作者

腾讯高级管理顾问

讲师介绍 大家都叫我“乔帮主”?这个绰号是我 2010年以领域专家身份加入百度PMO时得到的。 当时百度并没有工程生产力部门,而是负责软件过程度量的 SQA。在加入之后,该部门的职责已经改为:“通过引入先进软件研发模式,并在百度各产品线进行推广,从而提升生产效率“。

现在,DevOps 运动兴起,持续交付研发理念已被广泛接受。

而在当时,我们戏称自己是“丐帮”,因为持续集成和持续交付这种软件交付方式在当时还很难被人接受,所以只能向不同团队“兜售(祈求)”我们的持续交付研发方式,也不一定被人“理睬”。

而我一身正气,是不是和《天龙八部》中的乔帮主有点儿像,哈哈哈。

在过去的10年里,我为不同类型的企业提供组织转型和研发效率方面的咨询工作,今天这个题目是我对过去这么多年的总结。

更多的实践原则与方法在我的新书《持续交付 2.0》。本会场可以看到一些预览版,当然只有为数不多的几本,因为还没有正式印刷出版。这一版算是“限量版”啦,哈哈哈。

那么在过去的这些年里面,我遇到了什么?我在这个行业里做过很多角色,从普通工程师到架构师,从项目经理到部门负责人。

从小作坊式的软件生产,到大规模的瀑布软件开发方法。感觉做软件总是这么累,反反复复总是不流畅。

直到2002年发现了《解析极限编程》,觉得其中的开发方法有些不可思议,但觉得应该能有一些效果。

后来有机会在自己的团队中使用其中一些实践,当然根据自己的判断进行了所谓的定制(现在看来是不恰当的做法),得到一些收益,便并没有想象的那么大。

直到 2007 年加入思特活克公司(ThoughtWorks)以后,尤其是与Jez Humble(他是 DevOps 领域的世界级领军人物)一起负责一款软件产品开发以后,才真正体会到这种软件开发模式的魅力。持续交付这种开发方式的确可以让软件交付变得非常快。

然而,当时IT行业的绝大多数组织并不相信这一点,所以我就开始了我的布道之旅。

我在过去十年里也遇到过困难,走过一些弯路,今天就为大家分享其中的几个“陷阱”。提醒大家一点,这条路不太好走。

1. DevOps 运动诞生的必然与发展

在不同的时期,软件交付面临不同的困难,而行业中各种新名词的出现,总是想解决软件生命周期中的某个具体问题。

上个世纪60年代未出现第一次“软件危机”,所以我们从建筑行业借用了“工程”的概念,并产生了“软件工程”学科,并随之出现了瀑布模型,它是期望通过严格的重文档重流程的瀑布模式来解决业务需求多与软件人员能力及人员供给不足所导致的软件项目交付成功率低下问题。

然而,软件工程并未像建筑工程那样发挥相同的作用,软件项目成功率仍旧不高。

在90年代出现了很多轻量级的软件开发方法,更强调迭代与增量,与瀑布模式形成鲜明对比。

到了2001年,这些方法都被统称为“敏捷开发方法”。当在,强调迭代的同时,瀑布模型仍旧存在,很多团队在每个迭代的粒度内,还仍旧使用瀑布模型。软件团队经过几个迭代的开发以后,再把软件发布到生产环境上。

2010年《持续交付》一书发布,并描述了这样一种交付方式,即“持续交付”。让软件随时处于可发布状态,可以按需发布到生产环境。

这个时候,瀑布模型仍旧没有消失,只是它在一个更小的粒度上发挥作用,即单一个需求的力度。

下面这个环就是一个软件的交付环。

我们可以看到,在过去这么长时间,持续集成(CI)和敏捷软件开发方法(Agile)中的很多实践聚焦于解决从需求到构建出软件这一环节中各角色的合作。

而互联网业务的崛起,使得如何让构建完成的软件快速上线成为绝胜的关键因素。而这也是“DevOps“这个名词出现的巨大动力之一。

因为,此时传统运维的工作方式成了“瓶颈”,必须改变原来研发部门与运维部门之间的协作方式,才能让这一过程更加平滑流畅。

DevOps 强调的是软件开发团队和运维团队的敏捷协作,让软件更加平滑、快速进入到生产环境上,从而发挥软件价值。早在 2011 QCON 大会上,我有一个主题演讲,题目就是《 DevOps,让持续交付成为可能》。

其中,最后一个关键点就是:让运维人员参与到软件开发过程中,组建全功能团队,建立信任关系,改变原有的工作方式,从而提升软件的交付速度。

持续集成和敏捷打破了产品开发和测试之间的一个部门墙,让他们更加快速的能够迭代起来。

那么,迭代完之后呢,我们需要快速部署,尽早发挥软件价值。此时就有了DevOps。

DevOps 让我们的软件交付团队和软件运维部署监控团队能够合作起来。而持续交付1.0 需要将敏捷和 DevOps 结合在一起,才能从前到后贯穿。

持续交付并不仅仅指运维团队每天多次从产品库中取出二进制软件包进行自动化部署。这一点应该是大家想清楚的。

DevOps 到底是什么呢?由四位 DevOps 运动领军人物共同出品的《 DevOps 实践指南 》一书中,也没有对 DevOps 完整定义。事实上,它没有行业上统一的定义。

从我自己的理解的话,敏捷本身是一场运动,它旨在寻找一系列的方法和实践,以提升软件交付的质量和效率。

我把“质量”放在前面,是因为只有在确定质量水平的前提下,提升软件交付效率才更有的意义。

那么,DevOps 是什么呢?DevOps 也可以说是一场运动,它的目标与敏捷一致,如上图所示。

DevOps 已经成长近10年,行业内有很多很多的做法。上图是我在网上找到的一张截图,在这张图里面可以看到很多工具,并且都被称为 DevOps 工具。然而,这些工具已经存在很久了,比如Git(一种分布式代码版本管理工具)。难道企业使用了这些工具,就说明企业 DevOps 了。

很多企业说:“我要做 DevOps 了,我要雇佣 DevOps 工程师!”现在好像DevOps 工程师的招聘薪资也的确比较高。但是并不是使用了一些工具,雇了一些 DevOps 的工程师,你的 DevOps 就可以做得很好?

很多的企业想:“我要做敏捷,我要做 DevOps 。做了之后,软件交付速度就从一个月变成了两个星期,进而两天,甚至一天,或者更高。

然而,现实中的企业历程通常是下图蓝色曲线这样的。您可能已经注意到,曲线的后半部分是虚线。 为什么是虚线呢?因为只有很少的企业可能跨过鸿沟,持续提升。

1 鸿沟产生的原因?

当某个组织说:“我们要 DevOps 了”以后,会马上找来一批工具,再找一些DevOps 工程师,将它的现有流程做成一系列的自动化步骤(比如自动提测,发通知邮件等)。

此时,我们会得到了一些收益。当流程优化到一定阶段以后,我们会开始关注“测试提速”这个问题。于是,就会开始做一些自动化测试。

在做自动化测试时,遇到的第一个问题就是测试环境准备的自动化。解决这个问题之后,我们也会得到一些收益,这个收益的大小决定于原来这个环境准备工作到底有多“痛苦”!

当这一步准备好以后,测试人员可能就会开足马力写一些自动化测试了。最初的两个月里,大家觉得这个效果也还不错。然而,很快就会到达到上图中的第一个拐点。

此时很多人还没有意识到,所以仍旧会按照现有的方式,由测试人员增加更多的自动化测试用例。

一段时间以后,就会觉察到,效果不像早期那样明显提升了。这个时候,常见的选择有两种,一是继续坚持这样做下去,很可能收益会下降。 另外一种做法是保持当前这种现状。也就是说,大部分企业会停留在该曲线上那段平台期的某一点上。

此时,DevOps 的实施策略是“摘取伸手可得的苹果”。也就是:

(1)别让变动太多,太大;(2)先找容易的事情做。如下图所示。

为什么这个曲线最开始有一个提升期?是因为流程自动化等工作减少了每个交付迭代中的事务性成本。

从最终客户(用户)的视角来看,每个软件交付迭代包括两类活动,一是增值活动,另一类是非增值活动,也可以叫做事务性成本。

这部分事务性成本是什么呢?例如,测试活动、迭代计划会议、站会等等。我们希望在保证交付质量水准的前提下,将这些事务性成本变得更低,从而增加更多的增值活动时间。

当这些事务性成本降低后,我们的原有的交付周期中增值活动的时间就会变多。此时可以将迭代交付周期进一步缩短,从而让用户更快地得到软件。

但缩短到一定程度以后,你很可能会发现,每一个短迭代周期中的增值活动和事务性活动时间的比例会再次恢复到原来水平,如下图所示。这会让团队非常得恼火,无论从上到下都非常得恼火。

为什么会这样呢?举个例子,持续交付模式需要较多的自动化测试用例。而测试工作通常是由测试部门承担的。测试部门有人力投入到自动化测试编写之上。而最初写的自动化测试都是端到端测试。

随着端到端测试数量的增加,你会发现,维护这些测试用例需要很多的成本,很容易形成头重脚轻的情况,如下图所示。

这个时候就会有人跳出来,挑战道:“你投入这么多自动化测试的成本,收益是什么?投入产出比值得么?” 这种场景通常会发生在平台期。这就是很难再走下去的原因之一。

端到端的自动化测试运行成本高,维护成本高,诊断成本也高。而很多组织的测试人员并不具备编写低层自动化测试用例的能力。即使具备更细粒度的下层自动化测试用例的编写能力。

由于协作流程与组织文化等原因,也无法及时获得必要的写作变更信息,这一样会导致这些下层细粒度测试用例的编写质量,以及用例变更的及时性。

那么,如何跨越这个鸿沟呢?

2 实施 DevOps 的两个关键思考?

第一:正确认识“度量”

怎么强调度量都不过分。通常度量项有三种属性。包括它的可观察性、可行动性与时间性。时间性又分为引导性和滞后性,如下图所示。

有一些指标是可直接观察获得的,但是无法对它直接采取行动。例如千行代码缺陷数量,它是可以直接统计并观察到的,但它也有滞后性,因为当你得到这个数据之时,它已经成为事实结果。

与此同时,它也不具备可行动性,因为你无法采取哪些行动,直接降低这个指标。

相反,你可能使用一些引导性指标来指引团队的行为,从而可能达成想要的结果,例如代码review的数量、代码规范检查标准等。

另一个例子是:从提测到上线前发现的缺陷数量,这个指标也是滞后性指标,因为得到这个指标的数据时,它已经是一个结果。与之相比,自测的测试用例数量可能就是一个引导性的指标,而且是一个可行动指标。

我们假设:自测的用例数量增高后,提测后的缺陷会减少,但这两个指标之间的因果关系只是我们的推测,还有很多因素的影响。

软件工程中的一大难题就是“研发效率度量”。总会有人问,这个软件开发效率到底如何度量?我也一直没有发现一个非常有效的且业内可以达成完全一致的研发效率度量体系。

但我认为,在众多的指标中,每一个度量指标都是意义的,但它对于你所在组织是否有效,就不一定了。这取决于组织能力、产品形态与人员技能水平。

上图中,越靠近右侧的指标具有更多的过程引导性,而越靠近左侧的指标相对来说,就更多的是滞后性结果指标。两个指标之间的距离越大,离得越远,那么它们之间的直接相关性就越弱。而且,其中多个指标之间也会互相影响。

因此,在设计改进方案时,必须想清楚这些目标中,你到底要选择哪一组指标。当某一个指标发生变化以后,是否会引起其他指标的变化,预计这个影响有多大?这个影响预计需要多长时间才能够体现出来?

另外,引导性指标通常会有延迟效应,它的作用需要一段时间后之后才可能传导至对应的滞后性指标,甚至因为距离太远而无法被察觉过。

这些年积累的经验,我觉得可以从以下几个方面进行着手。

获取度量数据,需要一定的成本。假如当前没有任何准备的话,想要持续获得全面性数据,前期投入一定不小。

因此,初期可以采用抽样法以较小成本获得一定量可信数据,以展开改进行动。但这种方式可能会有偏差,有一定的风险性。

另外,我还想提及另一个突破性关键点。即“寻求第二序改变”。有一本名为《改变》的书,该书中讲到了“问题的形成和解决的原则”。

给我留下比较深刻印象的是,“第二序改变”可以引起更大的差异性结果。所谓第一序改变,就是指以系统本身结构不变为前提,对现状进行改变,通常这种改变并不会引起“质”的变化。要想带来“质”的变化,必须寻求第二序变化,即:通过对系统本身结构的改变而带来变化。

第二:寻求系统本身结构的变化

例如,改变自动化测试用例的使用者。在没有改变之前,自动化测试用例的使用者通常为测试人员。如果我们将它的使用者改为开发人员,此时,看待测试用例的视角,以及对测试用例的要求可能就完全不同。

通常为了让开发人员能够高效地利用这些自动化测试用例,改善开发人员的工作效率,这些自动化测试用例就必须符合四个原则,即:快、捷、信、时。

“快”是指每一个自动化测试用例的运行速度必须非常快。“捷”是指:一定要保证开发人员能够非常便捷地一键运行其指定的测试用例集。

“信”是指在测试运行完成之后,其结果是可信的。“时”是指用例准备的及时性。即当开发人员想要测试自己刚刚开发完成的功能时,最好自动化测试用例就已经准备好了。

如果所有的测试用例仅仅是针对那些非常稳定的功能特性进行测试,那么它对当前开发任务的作用就没有那么明显了。

自动化测试用例的使用者从测试人员改变为开发人员,这就是一个“第二序改变”。为了完成这种改变,就必须改变原有的思考和工作模式。

为了达到这些要求,我们可能需要将一些测试用例的层次从最上层的端到端测试下移到系统集成测试、组件测试,甚至单元测试,如下图所示。

这很可能会导致团队角色与职责的变化。因为这种变化打破了原有的工作流程与结构,就很可能带来新的改变。

这种改变可能就会改善我们的自动化测试用例数量的状态,并向着良性的正三角形发展。

到目前为止,我们讨论的都是“软件交付领域”的内容,也就是《持续交付 2.0》中所说的提升“快速验证环”的努力,即如何快速交付那些已经准备好的需求。

然而,从产品的角度考虑,这个闭环并不是一个完整的闭环,因为准备好的需求并不是问题的起点。那么问题的起点在哪里呢?当然是在业务领域。

我们开发软件,是为了解决某些业务问题。因此,如果我们从更完整的视角看待问题,那么软件价值的交付应该是两个环的闭环模型,如下图所示。

从“提问”开始,为什么要开发软件功能?做了它以后,我们期望对哪些指标产生怎样的影响,为什么我们认为会产生这种影响,这就是“锚定”。

有多少种不同方法可以达成我们期望的改变,这就是“共创”。到底哪个方案是我们认为最有可能达成我们目标的方式,这就是“精炼”。

然后才是“快速验证环”这才是一个真正的、完整的价值交付的环,从提问开始,真到问题是否得到解答为止。

3 DevOps 走向哪里?

最后,让我们畅想一下。在 DevOps 运动的催化下,未来的组织可能是什么样的?DevOps 强调通过使用共同的语言,让不同角色能够更紧密地协作,从而提升交付效率。而相同的目标更容易产生共同的语言。

对企业来说,更有意义的目标是业务目标。目前,很多 IT 组织并非以业务目标建立组织结构,而是以职能目标建立组织部门。

为了能够更好地完成业务目标,企业就需要考虑如何围绕业务目标来组织资源。并没有哪一种组织结构是完美的,但围绕业务目标来组织团队通常都是适合的。

“组织墙”总会存在的,当我们打破不同职能部门之间的“墙”,同时也会建立“业务单元墙”。只要保证这种“墙”是容易打破并重建的,那么组织就是健康的。

只有这样,我们才能建立一个灵活而又强大的弹性组织,它由一系列小的业务单元组成,以就对市场的发展变化。

需要强调的是,不仅仅那些直接服务于外部客户的组织是业务单元,服务于组织内业务单元的团队(例如基础设施服务)也应该按其服务的业务或内部客户不同而作为业务单元来对待。如何定义“业务单元”是一个复杂话题,因为其与企业内外部环境强相关。

当我们有众多业务单元时,这些小的业务单元之间要做到 “对齐”是一个巨大的挑战,尤其当业务单元之间存在协作时。现在业内经常提到的“中台”架构,似乎是对“小业务单元”相左。然而,事实上,这个“中台”也应该是由多个小业务单元构成,并要高度“对齐”的。

虽然,单一个体的效率最高(因为决策与行动一体化)。但是,个体的能量是有限的,所以我们仍旧需要高效沟通,以便“对齐”。

就像技术架构中的微服务架构一样,需要将很多的小业务单元高效地串联起来,才能真正发挥这种多个小团队协作的优势。如果没有协调好这些业务单元,那么可能提升了单一业务单元的内部效率,但整体的价值产出并没有增速。

那么,如何”高效对齐“呢?一种可能的方式(并不是唯一的方式)是参考”阿米巴经营“。日本京瓷公司是生产陶瓷制品的公司,是典型的生产制造行业。它由稻盛和夫先生创办,并在经营过程中总结出了“阿米巴管理经营方式”。

在2009年,稻盛和夫再次出山,成功运用这一管理工具,带领日航走出困境。日航是一家提供航空运输的服务性企业。

他将由生产制造行业中总结的“阿米巴管理”也成功运用于服务性企业,将日航30000 多名员工分成 10 人左右为一个最小经营单位的众多阿米巴,并让每个阿米巴作为独立经营核算,激活所有员工,让他们自己组织起来,为自己的目标工作。

要想完成这样的转变,必须从以下三个方面着手。一是软件架构,二是组织机制和,三是协作基础设施,如下图所示。

由于时间关系,我就不再展开讨论。在《 持续交付 2.0 》一书中完整地讲述了三个实践案例。

根据组织规模、业务目标、产品形态的不同,这三个案例选择了不同的实现路径。如果你对它们感兴趣,可以参考《 持续交付 2.0》的最后三章。

4 小结

在不改变系统结构的前提下,优化是容易进行的。但是,优化到一定程度以后,可能就需要寻找第二序改变,才能够”涅槃重生“,达到更上一层楼。

本文根据 DevOps 国际峰会(DOIS)2018 · 深圳站乔梁老师分享整理而成,经乔梁老师审定授权发布。

0 人点赞