持续交付2.0

持续部署实践 对 ToB 软件企业也是一样有效的,前提是:你真的理解「持续部署」

Image

“开发人员到底会如何应对「速度与质量」,是由他们的激励机制决定的,而激励机制是由团队文化决定的。”

Image

本文以最早提出「持续部署」和「免疫系统」的互联网社交平台 IMVU 的视角来讨论:「到底什么是持续部署?它有什么好处?」

IMVU的创始人之一就是 《精益创业》 的作者 Eric Ries 。

持续部署是他非常重要的关于 「从生产环境和客户那里学习」的观点之一。

1

2009年,50+ 工程师
一天部署 50 次

在 Eric Ries 所倡导的 《精益创业》 所有实践中,没有哪个实践比持续部署更有争议。

他认为,持续部署是指:让公司在几分钟内发布软件的过程,而不是几天或几个月才发布一次。

他的一个创业公司 IMVU 使用这个持续部署流程,50+个开发人员平均每天部署50次 。

这引发了一些争论。

有些人说:这种快速发布流程会导致低质量的软件,或者阻碍了公司的创新。

如何我们能接受由客户来评判,而不是专家的判定,那么,我想这些说法就很容易消散了。

一个更为常见,且更为困难的问题是:

「如何回答那些只想知道这种持续部署是否可以用于他们自己的业务、行业或团队的人们?」

2

IMVU的历史

尤其引人关注

20011年,IMVU 作为一个有数百万用户的互联网公司,它的做法看上去与那些客户要在软件发布前需要严格审核的 toB 企业软件公司(例如,财务软件,CRM,或者企业安全软件公司等)没有太多关系。

持有这种观点的人实际上并没有真正明白持续部署的关键点,

因为他们关注点都放在了具体的「持续部署」的实现上,而不是通用原则。

目前关于持续部署的文章,都关注于「具体如何实现」, 但真正重要的是「为什么做?」

(如果你想了解如何开始做持续部署,请参阅「实现持续部署,只要五个步骤」)。

持续部署的目标是:

  • 通过减少批量处理的大小 ,

  • 并加快团队工作的节奏,

  • 来帮助开发团队在其开发流程中消除浪费。

它让团队能够一直处于一种可持续的平稳流状态, 让团队更容易去创新、试验,并达到可持续性的生产力。

而且,这也很好地支撑了其它的持续改进系统,比如「 五个为什么 」。

3

西部牛仔 VS 质量卫士

在开发中,浪费的一个最大来源是「double-checking」。

想像一下,在传统瀑布开发环境中的一个团队,

没有持续部署、没有测试驱动开发,甚至没有持续集成。

当开发人员想要提交代码时,就到了一个令人担心的时刻。

此时,开发人员有两种选择:

  • 马上直接提交;

  • 再检查一下,确保不会出问题。

这两种选择都很有吸引力。

假如马上提交的话,就可以说「提前完成任务了」。

可是,如果提交后引起了问题,那么之前的工作速度必然要打折扣。那他们为什么不再多花五分钟时间,确保自己的提交不会导致问题呢?

事实上,开发人员到底会如何应对这种问题,是由他们的激励机制决定的,而激励机制是由团队文化决定的。

  • 导致问题后会受到多么严重的惩罚?

  • 谁最终会承担这些错误带来的成本?

  • 时间计划有多么重要?

  • 团队是否以尽早完成工作来做评价?

我们应该意识到,在这种情况下,其实并没有所谓正确的答案。被这种选择性所折磨的人最终很可能哪种都做不好。

开发人员最终会走向两个极端:一些人认为应该尽快完成事情,另一些认为应该细心地做工作检查。

(实际上,绝大多数开发人员会选择第一种方式:赶快提测,让测试人员去测试吧!!!因为他们认为,测试人员就是为他们做测试工作的。)

从长远来看,二者之间的任何一个中间状态都无法长久。

一旦出了问题,无论你怎么去细心解释当时是如何做决定的,都不会令人满意。

毕竟,你要么可以做得更快一些,要么可以做得更细心一些。

「要是你能提前知道问题多好呀?!」

事后再回头看看当时的那些评判,它们好象都有问题。

然而,从另一个角度上看,这两种极端的做法都很容易起到自我保护作用。两种方式都有借口:

「的确是有几个bug,但我一直在以一个安排得非常紧的时间表来完成任务,有几个bug也是再所难免的」

「我知道你想快点完成这个事儿,但你要知道,我要确保绝对没问题的情况下才能交付给你,所以等一等是值得的。」

这两个极端的立场在开发团队中会发生「派系」冲突,可能产生很多不愉快。

管理者开始记下谁在哪个派系,然后再依此来分派任务。

当在最后一分钟拿到了某个新功能的请求,先找个「牛仔英雄」完成它。然后,在下一次版本发布中再找个「质量捍卫者」来「擦屁股」。

两边都开始从他们各自的视角来思考:

「那些家伙没有看到快速行动带来的经济价值,只在意他们那完美的架构图。」

「那些家伙太懒了,根本没有专业精神。」

在我看来,这些都真是太浪费啦。

其实,上述这种结果是完全符合逻辑的,因为,对于那种大批量生产的瀑布开发流程来说,它迫使开发人员利用传统的「时间/质量/成本,选择其中的两个」的谬论,在时间和质量之间进行权衡。

由于得到的反馈速度很慢,所以因某个错误引发的问题与做出决定之间有很长的时间,这也使人们很难从中学习。

因为每个人都在最后的某个时间点同时做整个版本发布的集成工作(因为并没有尽早集成的激励机制), 要在很大的时间压力下解决这个集成过程中发现的所有问题。

这一点在现今软件项目中,仍旧频繁发生。见文末的参考阅读。

某些特性就像泡沫一样,看上去做好了,很美,但不得不等到下一次发布才行。

然而,一旦这些特性被推迟了,就会增加下次版本发布的工作量。这就会导致下一个版本的时间压力等等。

另外,在生产环境中代码运行的方式可能与其在测试或试运行环境中并不完全一样,这也导致每次发布之后马上就会有一系列的 hot-fixes 。这也会增加下一次发布的工作量,也就意味着每个发布周期从一开始就已经落后了。

有很多次,当一个遇到这种情况的开发团队问我时,他们都想让我帮助「fixing people」。

这种现象心理学上叫作「基本归因错误」,即:

人们倾向于认为其他人的行为来源于其基本属性,如他们的个性,道德准则,或士气,甚至当受到所在环境的影响时,我们也会为自己的行为找借口。

所以,在这种环境下的开发人员,他们的心灵深处也会认为其团队的其他开发人员也是行动缓慢的老学究或邋遢的码农。

事实并不是这样的,他们只是让他们的动机搞砸了。

4

持续部署
为什么会起作用?

首先,持续部署要将两种不同的「发布」概念区分开来。

一种是工程师所说的发布,也就是「部署」:将代码部署到生产环境的过程。

另一种是从市场人员的角度来看的发布,也就是「发布」:让用户看到。

在传统的「批量及排队」这种开发模式中,两种概念是相联的。一旦新版软件被部署了,所有客户也就能看到它了。

这就要求在部署之前,我们要在特定的试运行环境或测试环境中完成本次发布相关的所有测试。这就使得从写完代码开始,到生产环境部署这之间的这段时间里,由于某些未曾预料到的问题而令本次发布变得不可控。


在这些开销中,由于市场发布与技术部署的合并,让交付活动的协作开销急剧增加。

而在持续部署环境中,一旦代码写完,这个变更就开始向生产环境进发。也就是说,我们经常只部署某个特性百分之一的功能,尽管客户可能要在很久之后才能看到它。

事实上,一个新特性的绝大部分工作都是用户无法看到的。相反,这个特性与之前已完成的特性之间却有很多集成点。

想像一下,当我们想要在系统中传递一个新增的参数时,就需要修改多个API。这些修改通常应该没有「副作用」,也就是说,它们不会影响当前系统的行为——这里要强调一下「应该」两个字。

实际上,很多缺陷是由于那些修改中不常见或没有意识到的副作用引起的。对于那些只是影响生产环境中的配置参数的很小的修改来说,也是一样。

尽快得到这种反馈是最好的,而持续部署恰好提供了这样的途径。

持续部署也扮演了速度调解器的角色。

每当部署流程遇到了一个问题时,就需要有人去诊断。在诊断期间,其他人就不能进行部署了。当团队已为部署做好准备,但部署流程被阻塞时,他们就要马上去帮助诊断并修复部署问题。

与之相反的做法是:团队其他人继续去写更多的代码,但是并不部署,那么这些新代码就会不断堆积,使批量变大,这对每个人都是一种损害。

对于那些通过度量个人效率来衡量其流程的团队来说,将「持续部署」作为速度调解器是一个比较难以置信的工作方式。

在「度量个人效率」这种管理环境中,管理者和每个工程师的主要目标是:保持忙碌状态,写代码的时间尽可能地多。不幸的是,这种视角忽视了团队的整个产出。


即使你不采纳我所提倡的激进定义,比如「从客户那里学习」,让每个人都保持忙碌状态仍旧是局部优化。

  • 当你正在追踪和修复集成问题时,其它人写的代码很可能会由于冲突而不得不回滚。

  • 配置不匹配或多团队之间的冲突都可能会怒导致同样的结果。

在这种情况下,对于整体生产率来说,最好是大家停止编码,开始讨论。一旦找到如何进行协作,以便不会导致工作重来,再开始编码,这样生产率才高。

再回到我们之前讨论过的两种类型开发团队成员(牛仔和保质派),看看持续部署如何改变他们所处状况的症结。


首先,持续部署对于双方来说,都能促进学习和专业地开发。双方不必争论哪种是写代码的正确方式,而是每个人都可以直接从生产环境上得到学习的机会。这就是「让错误成为你的老师」。

做出更好的发布计划、更详细地评估、架构或集成,只会减轻症状。而传统方中,解决这个问题的技术是以时间表填充、额外的集成时间、代码冻结等形式添加大量队列。

事实上,大多数组织并没有意识到,在单个开发人员的自我学习产生的估算中,这种时间填充已经占据了很多。但是,这种时间填充方式并没有帮助,它只会减慢整个过程。

正如所有开发团队都会告诉你的那样,时间总是不够的。事实上,过度的时间压力正是他们认为自己会遇到这些问题的首要原因。

因此,我们需要找到在系统级运行的解决方案,以使团队摆脱这种钳制行为。

  • 敏捷软件运动已经做出了许多贡献;

  • 持续集成,这有助于加速缺陷反馈;

  • 故事卡和看板减少了批量大小;每天都有人站出来提高速度。

  • 持续部署是另一种这样的技术,它具有一种独特的能力,可以更好地改变开发团队的动态。

5

持续部署实践
为什么会持续发挥作用

在「度量个人效率」的系统中,每个工程师的主要目标是保持忙碌,尽可能地将他或她的100%的时间用于编码。不幸的是,这个视图忽略了团队的总体吞吐量。


即使你不采用激进的进度定义(比如,我提倡的如何有效地研究你的客户群),「让每个人都忙碌」仍然是次优选项。

当您正处于修复集成过程中发现的问题时,任何人正在编写的代码都可能会因为冲突而被修改。配置不匹配或多个团队互相踩脚也是一样。

在这种情况下,人们停止编码并开始交谈,对整体生产力来说会好得多。一旦他们找到了如何协调他们的行动,这样他们所做的工作就不必返工了,重新开始编码是很有成效的。

回到我们的开发团队,它们分为「西部狂野派」和「质量保守派」。

我们看看「持续部署实践」如何改变他们的状况。

其一,持续的部署促进了学习和专业发展。每个人都有机会直接从生产环境中学习,而不必为正确的编码方式而争论。这就是「让你的失败成为你的老师」这句公理的含义。

如果一个工程师倾向于快速交付,他们可能很快发现自己被「集群免疫系统」逮个正着。

集群免疫系统,即:cluster immune system,它由持续集成服务和 5个 whys 组成。

与传统团队的那种高风险问题相比,此时遇到的问题风险都很小,大多数仅影响自己或者比较小的范围。由于反馈迅速,牛仔们开始意识到,到底有哪些测试、准备工作和检查工作,会让他们工作得更快。他们就会知道:原来还有这样的东西(工作方式)要可以这么快反馈。

但是,对于工程师来说,总是有一种在交付前希望等待很长时间的趋势。对于这样的人,批量工作越大,集成就越难。

在IMVU,偶尔也会招聘到一些从非常传统的组织里出来的工程师,他们在那样的公司里已经养成了那里的「最佳实践和开发习惯」。有时候,他们希望自己使用自己的分支进行工作,并在最后再做集成。

尽管 IMVU 总是会尽最大的努力去说服他们不要那么做,但如果他们坚持要那样的话, IMVU 也会鼓励他们在 IMVU 试一下的。最终在一两个星期之后,就会很高兴地看到他们还是回到了「持续部署实践」的主流。

像「向墙壁扔皮球」一样,在一个code bouncing的环境下,如果有人试图一次性提交一个大版本,他们首先就会遇到代码集成的冲突,这就要与团队中的很多成员进行沟通,了解如何恰当地解决这些冲突。

当他们正在解决冲突的时间,又会有其他工程师提交了新的变更,所以,新的冲突又会出现了。这个循环一直重复,直到解决所有的冲突,或者要求团队的其他人员先不要提交代码。

此时,更有趣的事情开始了。把这一大堆修改扔到了持续集成服务器上,一定会令增量部署系统和实时监控系统趴窝。

所以,这一大包修改就被回滚了。当这些旧问题被解决时,集成分支上已经有更多新的修改被提交了。

除非冻结整个团队的工作,但这有可能会持续几天的时间。假如全面要求做这种提交冻结的话,那会令其他人的工作也形成堆积,这就会进一步导致连续的 code bouncing。

根据我的经验,只要一两次这样的事情就足以让那些想做批量提交的同学回心转意啦。

所以,其二是由于持续部署鼓励学习,随着时间的推移,使用这个实践的团队会越来越快。

那是因为,每个人的动机都与团队的目标一致。每个人都在工作中消除浪费,这种效率提升得到的收益将会大于那些因为要做持续部署而需要构建和维护的基础设施而增加的开销。

事实上,假如你也经常使用 5个Whys 的话,你也可以用一种完全增量的方式建立这种基础设施。这个过程真的非常有意思。

最后,还有一个收益,那就是「士气」。

曾经有一个人问我:持续部署是否会对士气产生不良影响?他是一个管理者。

他担心,做这种更快速的发布会令工程师感到更大的压力,让他们觉得自己一直在救火和发布,根本没有时间做「真正的工作」。

事实上,通过减少每次发布的开销,每个工程师都可以有他个人的发布时间表。

也就是说,只要他们已经准备好部署了,就可以部署。

所以,即便是在半夜,如果你的特性做好了,你也可以提交、部署,并马上告诉客户这个新特性。

没有额外的申请审批、会议,或者协作要求。

只要有你、你的代码和你的客户就行了,听上去相当不错吧~

【参考文章】

1、新团队,刚接触持续交付实践,遇到这种状况,怎么办?(内有福利)

2、如何通过累计流图,发掘更深的项目管理风险(PART TWO)