乔梁,《持续交付》中文版译者,腾讯高级管理顾问,“轻敏捷”方法创始人,持续交付先行者,映客、卷皮、墨迹天气等多家移动互联网公司高级管理顾问,也为魅族、上汽、平安等不同类型的公司提供组织管理咨询服务。
我与《持续交付》之缘
《持续交付》是我在2011年翻译的一本书,由人民邮电出版社出版。今天给大家分享的这段主题,对我来说,也是对”持续交付之路“的一次小结:为什么炒那么多年的”饭“,到现在好象还没有”炒“好?
2001年接触敏捷
我最早接触敏捷这个概念的时候是2001年。我看到了一本书,名叫《解析极限编程》,当时觉得非常的棒。因为做为软件开发者,感觉这本书可以解决我工作中一直被困扰的难题。但也并没有马上使用,因为好象太难了,不太现实。有一些实践,当时,我也不太能完全接受。
2004年引入敏捷实践
2004年以后,作为一个产品的技术负责人,在我的团队里引入相关的一些敏捷实践,但是在我们公司里发现这个很难推行开来,觉得成本太高了,于是,我选择做了一些折中方案,比如不做结对编程,但做code review。
2007年加入ThoughtWorks
但实践结果并没有我预期的那么好。在2007年,我加入了 ThoughtWorks,它是当时在国内大力推广敏捷开发方法的先行者。加入 ThoughtWorks,我就想知道他们是怎么在他们的软件项目中运用敏捷开发方法的。比较幸运的时,正好与《持续交付》这本书的作者 Jez Humble在同一个产品团队,这个产品就是goCD(它最初的名字是Cruise)。他是这个产品的产品经理,我是作为业务分析师加入这个团队,后来作为产品的delivery manager。在工作过程中,真正地理解了敏捷开发方法的精髓。
2010年《持续交付》的手稿
在开发这个产品的时候,Jez Humble就在写这本书。我在第一时间看到了这书的手稿,觉得非常棒,就开始积极联系国内的出版社,看看哪个出版社能引入这本书。
2011年《持续集成》翻译成书
当我完成这本书的翻译,并出版时已经是2011年,那时我已经加入百度,并工作了一段时间。一会儿后面提到的第一个案例也是在百度的,在座的刘俊老师,当时就是这个案例项目的运维工程师。
2013年成为外聘顾问
2012年,我开始作为外部顾问,帮助腾讯多个团队去做组织及研发管理上的改进。直到现在。从2007年开始,我的所有工作中都会看到“持续交付”的理念和做法。
什么是持续交付
新兴的IT词汇?
IT行业新词多,我们今天提到的我想解释的可能就图片上这么几个,持续集成,敏捷软件开发,持续交付以及DevOps。最后面的这两个词汇是今天想要讲的主题,之所以这么说是因为我在2011年和2012年的时候,在QCon技术大会上就讲过一个主题,名为“DevOps,让持续交付成为可能”。所以,DevOps并不是什么新鲜的东西,也没有什么神秘。
从场景出发理解持续交付
当我们讨论这个名词的时候必然和场景相结合,通常在一个软件产品团队里,总是会谈到这样四个角色————产品、研发、测试、运维。几乎所有的公司,都会以员工的技能将他们分成相应的四个部门,然后,自然而然就会出现部门墙。用通俗的话讲,就是“屁股决定脑袋”。
那么来看看刚才提到的那四个IT热词,根本想解决的问题是什么。
持续集成,你会发现,这个实践的参与方是我们的开发团队和测试团队,你做好了持续集成,会逐步打破开发和测试之间的墙。
敏捷开发,则引导往上游走了一步,让PO(在XP方法中,叫现场客户)卷入进来,试图消除业务需求与产品研发之间的墙。
DevOps,则想要解决的是运维团队和研发团队之间的墙。
持续交付,从我的理解,持续交付则是希望端到端的去解决隔离墙的问题。然而,在《持续交付》这本书里面,大篇幅讲了很多具体技术原则和技巧相关的内容,并没有把这一点提到一个特别高的高度上,我认为这算是《持续交付》这本书的一个不足之处吧。
从理论出发理解持续交付
什么是持续交付? 从上现这个定义来看,持续交付本身是一种能力,什么样的能力?以一种可持续的方式,安全快速的把你的变更,无论是features、配置管理、用户体验,放到你的生产环境上让用户使用。所以说持续交付本身定义的是一种能力,一种软件团队端到端的交付能力。
当很多人听到新的概念的时候,都会有一些兴奋,“又出来一个新的,正好解决了我的问题,让我们动手干吧!”。对它有特别大的期待。然后你就会在各大招聘网站上看到大量招聘DevOps工程师的广告。在2013年的时候,甚至有很多公司在说:”我们要有一个部门,叫DevOps部门“。
其实这个和DevOps所倡导的恰恰相反,因为当你增加这个部门的时候,很可能实际上会再多了一堵墙,DevOps和Dev和Ops之间到底是什么关系,平白无故为什么又多了一堵墙呢?DevOps运动本来是要打破开发团队和运维团队之间的隔阂啊?
那么,到底哪条路是正确的呢?这是仁者见仁、智者见智的事情。接下来把我做的两个案例跟大家分享一下,我最后会总结一下我在这里的一些思考。
案例一,在百度的持续交付案例
这是百度大厦,2010年下半年我加入百度,并在2011年指导大搜索部门的一个架构服务组做项目改进。当时我们在下面几个维度进行改进,它们是持续集成、环境部署、配置管理、数据管理、测试管理、发布管理。
《持续交付》一书上的成熟度模型
当然《持续交付》那本书的第15章也有一个模型。我们在这个团队里,因为它是一个后端架构服务的团队,C/C++代码,我们对开源代码也进行了改造,所有模块的代码加在起来,也有几百万行了。这个团队原来的节奏基本上是每三个月发布一个新版本。在刚才我提到的这几个角度里做了很多实践。
在百度的看板实践
图片上的这个白板是他们的故事板。而那个灯是持续集成实践中,显示集成状态(失败,或者成功)的。只要你入了工作区,就能看到持续集成的状态。如果这个灯是红色的,你就知道刚刚的一次构建失败了,有人正在修复。如果是绿色的,就说明现在的代码质量还不错,一切正常进行中。这种方式有很大的视觉冲击力,督促团队保持质量。
持续集成六步法
这张图是持续集成六步提交法。这是团队开始启动这个试点项目时共同约定的一个行为规范。只要是与代码相关的操作,你的工作步骤就应该是这样的。
关于测试的实践
在测试方面,我们在项目启动时也有一些约定。图上是一个我们自己的测试金字塔。对于最上层的系统测试,我们会根据具体情况,决定是否对新功能写自动化测试用例。对于第二层的子系统测试和模块测试,我们决定全部使用自动化测试用例。而最下层的单元测试,我们决定在刚开始的阶段,并不引入它。
当然,为了让上面提到的持续集成和自动化测试实践能够真正变得具有可操作性,我们在编译和测试系统也做了一些优化。通过引入分布式编译技术,对编译脚本进行优化,以及在分布式编译系统上加入编译缓存技术,让持续集成能帮助开发人员节省更多的时间。
最后的结果
当团队具备了持续交付的能力之后,团队希望更高频率地发布版本。当与运维同学沟通这个需求时,他的回应却是一个非常为难的表情。问他原故时,他说:“开发同学搞的三个月一个版本都质量那么不靠谱,现在要两周发布一次,我运维事故怕要多几倍了吧?”
当时的一个业务运维人员,本身就要负责多个业务单元。而当前这个业务单元每三个月部署一次,每次需要花费两天的时间,在三百多台机器完成所有的升级部署工作。现在要两周发布一次,这就相当于把工作量提升了数倍。因此,运维第一反应是排斥这么频繁发布软件服务的。
后来我们想了很多自动化的方式,让运维同学的工作量降下来,而且运维质量提高了。我们所有的部署的脚本(无论是开发环境、测试环境,还是生产环境),都由运维同学提供。这样,这些脚本在开发环境和测试环境上就会得到充分地应用,同时也是对它们的测试。
经过半年多的运行,效果非常明显。原来这个团队的节奏是三个月一个版本,在这次改造之后,变成了两周一个版本。对于一个后端负责架构改造的团队来说,这是相当不容易能够做到的。
试点项目结束半年以后,我与这个业务服务的项目经理聊天。他说团队其实能做到一周发布一次,但客户方觉得两周的节奏已经完全满足他们的需求了,所以也就没有执行一周发布一次。
这就是说:“只要团队具备能力,就可以随心所遇。愿意一周发布就一周发布,想两周发布一次就两周发布一次”。这个试点团队并没有利用到组织的力量,团队自身的改进动力让它自身的工作方式得到了改善。然而,当在三万英尺的高度来看俯瞰全局时,我就发现,这个试点的小团队是非常美好的局部,放到整个大环境中,就会产生一种无力感。如何让这种工作方式能够快速地推广出去,让所有人都受益呢?
案例二,在腾讯的持续交付案例
明明感觉很好是对的事情,但是却总是有一种无力感,怎么办?
2013年我受邀到腾讯,在腾讯负责一个产品的研发改进工作。这个团队的规模约400人。
新团队的情况
当时,这个团队设想得很好,希望每两周发布一个beta版,每个月发布一个全网稳定版本。然而,现实是:可能两三个月都搞不出来一个可以全网稳定的发布版本。就像图片上的情况一样,理想中是整整齐齐的通向最终目的地,而实际的情况则是崎岖坎坷的。
这个团队人员多,流程多,各种延迟也就相应增多,同时,团队面对的问题也很多。
到了这个团队以后,他们我了描述了一下团研工作情况,上面罗列了他们在项目开发的过程中遇到的各种问题,类似于上图所示。
注意:这不是服务端软件,这是一款PC客户端软件。
最终实现的成果
面对如山的问题,我仍旧用时三个月时间,通过改进做到每天有两个beta版本可对外发布,每周一个候选稳定版。每月一个全网稳定发布版本。
改进后,软件的基本质量得到保障,crash率下降了90%,产品品牌在腾讯精品软件中排名第五,进步排名第三。而在前一年,这个产品被评为腾讯内部所有产品中最需改进的产品第二名。
改进实施步骤
组织架构解耦
我们在这个团队里做了一个组织架构的解耦,根据我们的业务来组成不同的团队。每个团队里可能包含产品、开发、测试等不同角色的成员。当然,这里的“可能包含”是指:根据业务的不同,有的团队里没有产品经理,而有的组里可能没有测试人员。我举这个例子,并不是说一个组或一个业务里,一定要有产品经理,或者一定要有测试人员。具体团队组成需要根据实际情况来组织。但是每一个团队都能负责一块小的业务闭环,这是最重要的。
当我们把组织解耦做完之后,我们发现,按照业务来这么划分后,原来的软件系统架构不适合团队协作了。为什么呢?因为整个系统架构就像这个意大利面条一样交织在一起,就是现在经常提到的“单体系统”。这不利于每个业务闭环团队各自按自己的节奏工作。
软件架构解耦
所以,我们做的第二个事情就是:软件解耦。我们花了一定的时间和工作量,把整个系统在架构上做了一次调整,根据现行的小业务团队,基于业务小闭环模式来做解耦。
当我们做过架构解耦后,新问题又浮现了出来。在过去,所有人都绑定在一起发布版本,因为他们原来的模式就是一起工作,一起发版本,就像图片中被绑在一起跑步的同学们。现在,每个小团队各自负责自己的业务闭环。所以,很多业务团队说:“我自己想跑得快一点儿,我的功能已经开发完成了,为什么还要等其他团队,跟他们一起发版本呢?我们能不能在不伤害用户的情况下自己团队发自己的版本?于是改进还得继续。
配置管理&一键式
接着我们继续做了非常好的配置管理系统、发布系统,用来实现:在不伤害用户的情况下,团队如何自己发布版本。
最终实现了前面提到的效果:从2个月到2个小时。这2个小时是什么概念呢?发版前的测试阶段只需要2个小时的时间。只要测试没有发现问题,就可以外发(改进之前,每个版本在最后的系统测试,需要两周的时间)。如果发现问题,则会直接将代码回滚。这样,就不会耽误其它团队的版本发布了。
现在,你会发现:我们的改进步骤与前一个案例稍有不同。这个案例一共是四个步骤。第一步:组织解耦;第二步:架构解耦;第三步:配置管理升级;第四步:将一切自动化,提高效率。
案例反思
做了这个案例之后我就思考这样一个问题:这两个案例有哪些不一样之处。(1)产品团队的大小不同(一个300多人,一个10多个人);(2)产品形态不同(一个是PC客户端软件,一个是后台服务;(3)一个从整个团队组织架构入手;一个从基础设施入手。
那么,在百度案例中用的这个成熟度模型,是正确的吗?看上去是正确的,但还有一些瑕疵。因此,我在指导腾讯的产品团队时,改进了一下,我称之为“持续交付七巧板”。
除了在百度案例中所涉及的与技术基础设施相关的那一部分内容之外,我还加入了另外两块内容,它们分别是(1)团队协作机制;(2)系统架构适应性。
为什么要用“七巧板”这个名字呢?我认为,基本因素只有这么多,但是,你可以根据产品形态以及所处的发展阶段、团队规模,以及组织架构的不同,拼搭出不同的研发管理模式,而不需要一模一样。
《持续交付》三步走
那么,这两个案例有哪些是一致的。我认为,做事的方式是相同的,都是三步:我称之为“持续交付”三步走。
第一步 确定目标
你要达成什么目标?这个目标在团队中是否达成了共识?这个目标最好能够包含业务目标,而不仅仅是“提高工作效率,或工程效率”这样比较宽泛的目标。当团队有业务目标驱动的时候,更容易团队一致。比如,“缩短发布周期”只是一个宽泛目标,而“将发布周期从两个月缩短到一个月”,就是一个比较明确的业务目标。因为发布周期的缩短可以为业务带来更大的灵活性。
第二步 制定机制和方法
当定义了业务目标之后,就需要制定合理的协作机制?比如,如何拆分你的团队,团队之间如何协作,你的架构应该是什么样子的。所以一定要从业务目标出发来讨论这样机制与方法。
第三步 完善配套基础支持
在制定和机制和方法后,就需要团队执行。因为不可能在事先计划好所有的内容。在执行过程中可能还会遇到一些困难和障碍。此时,一定要坚持目标,想办法移除障碍,持续改善。而不是放弃或走回头路。
这就是我的小结————“持续交付”三步法。
尾声
为什么有这样的思考呢?因为在过去的几年里,我辅导过很多个公司,有知名的互联网大公司,也有两三百人的移动互联网公司,还有传统IT公司,一直使用“持续交付”三步法和“七巧板”来指导自己的咨询工作。
最重要的一点,你要知道你解决的是什么问题。
本文转载自公众号 「DevOps 时代」。
====================================
想更深的理解持续交付?
想更透彻的领悟 DevOps?
来 DevOpsDays 上海站吧
乔梁老师将带来精彩的演讲:《持续交付与 DevOps 精要》
点击“阅读原文”,关注 DevOpsDays 上海站