在意大利罗马召开的DevOpsDays上,我进行了题目为“度量驱动开发”的演讲,这篇文章以演讲内容为基础。
如今,IT世界里的发布已经变成几小时内的事情,甚至几分钟就能完成。所有的内容都要垂直伸缩、水平扩展。因此,有一个良好的监控系统是必需的。在很多IT组织里,应用是业务的核心。但监控却由不写应用的OPS(运维)团队单独去做。为什么会这样?如果是这样的话,为什么需要改变?又该如何去改变?怎样才能得到更好的结果呢?在这篇文章里,我将分享我的想法和来自于我和DEV(开发)团队一起工作的经验——让度量变得有意义。
本文描述的观点来自我在Adform公司任职IT架构师(联系开发团队和运维团队)的工作经验。Adform是一家数字广告公司,有自己的开发团队(65人)和运维团队(8人)。运维团队负责发布流程和开发环境,并负责准备和维护生产环境里的网络和服务器。开发团队则负责维护他们编写的应用,其中包括发布到生产环境里的应用。下面的内容基于我们的实际经验,这些经验有助于开发人员挖掘度量信息和监控信息,但在原来,大家都认为度量和监控应该是完全由运维团队关心的。
什么是度量驱动开发
你可能听说过广为人知的TDD实践——测试驱动开发,也可能听说过鲜为人知的BDD——行为驱动开发,或者可能听说过最不为人知的ADD——混蛋驱动开发(在Scott Berkunn的博文里可以看到一个不错的开发实践名称列表)。但度量驱动开发(MDD)是本文才提出的。
那什么是MDD呢?我认为MDD是用度量驱动整个应用开发的实践。在使用MDD的公司里,所有东西都是可以度量的,无论是性能和使用模式,还是收益。此外,开发人员、运维人员、甚至业务人员所做的每个决定都是基于度量结果的。度量用来监控团队的绩效、解决性能瓶颈、估计硬件需求,或者在开发生命周期的任意阶段达成其他目的。
度量驱动开发的主要原则有:
- 给度量拥有者分配度量项
- 创建分层的指标,相互关联、发现趋势
- 利用度量做决定
每个度量项都应该有一个拥有者,他/她要掌握一定的知识和方法来推行、维护确定的度量结果。度量拥有者负责应用、服务,设置运行应用和服务的服务器,确保能正常监控、收集结果。度量拥有者要获取现有度量项的最新结果,还要为新应用或功能设立新的度量项。
对度量进行结构化也很重要。按照一定标准分组或分层的指标能确保所有人(从业务人员到开发人员)更好地理解它们。而且指标分层后,能更容易相互关联、发现趋势,也能更快地找到、解决问题。
MDD让整个开发过程具备了可见性,所以大家能迅速而又准确地做出决定,错误也能被立即发现、修复。此外,可以度量的内容都能进行优化。换句话说,MDD能让你为应用“把脉”,并给你提供了一个持续改进的机会。
最后,利用度量给Sprint设置目标,MDD也能借此很好地和其他惯常实践结合起来使用,比如TDD、BDD或Scrum。度量也能发现问题和生产环境中的使用模式,这在验收测试过程中很难被注意到。一个例子是Lance Armstrong Bug:代码在测试时永远不会出错,但还是有证据表明它和预期结果不一致。另一个例子是从不会被使用的功能的业务Bug。这些Bug相关的证据可以用度量来收集。MDD确实能实现集中、高效的开发过程,过程回顾可以提高应用使用率。
谁创建指标?
当我们从无到有开始做一件事情的时候,你会有机会重新思考一些概念,给流程加入一些创新,甚至完全修改流程。我们在Adform就做了类似的事情。我们写完需求、构想好完善的监控解决方案后,发现期望和现实很不匹配。我们本想收集更多应用和服务相关的信息,因为它们带来收入和竞争优势。但监控完全由运维团队去做,他们对基础设施有深入的了解,却不怎么了解应用和服务的内部工作原理。
公司不会因为他们的服务器运行稳定(尽管这很重要)和有10G互联网连接而赚钱。公司赚钱是因为他们的应用和服务提供的功能,以及功能运行稳定(这和“服务器运行稳定”是不一样的)。因此要快速发现问题,把真正编写应用的人引入监控流程是必不可少的。事实上,当应用和期望不一样的时候,开发人员能很容易看出来,因为产品就是他们开发的,他们掌握着产品相关的所有知识。
最重要的是,开发人员去监控还有更多好处:
- 开发团队能在开发过程中把监控点嵌入到应用里去
- 开发团队能从生产环境里快速获得应用相关的反馈(性能、Bug、使用模式)
- 开发团队能在开发过程中学习基础知识,可以预见一些瓶颈
运维团队长久以来一直在做监控——CPU、内存和IO已经溶入到他们的血液里去了,至于应用和服务的指标,拥有者应该是开发团队。开发团队掌握着应用相关的所有知识,还有改进所需的所有技能。这就是运维团队为什么不能单独做监控的原因。开发团队应该和运维团队一起设立、维护指标。在接下来的部分里,我将介绍我们公司是怎么开始改变、如何把开发人员引入监控和度量里的。
在RTB(实时竞拍)项目中应用MDD
经过一个理解、学习、失败、最终成功的过程,我们才帮开发人员掌握了度量。情况并不简单,开发团队从来没用过度量,而且突然要依靠度量结果去做决策。这个是漫长而艰难的过程,很多因素都会影响最终结果,比如公司文化、员工态度、管理层、甚至工作习惯。为了让管理层和开发团队“买账”,先把度量的价值展示出来就很重要。我们偶然在一个名为实时竞拍(Real Time Bidding)的项目里完成了这件事情。
RTB是一种相对较新的买卖方法,会实时在线显示广告,每次显示一个广告。简而言之,为了在特定网站向特定用户显示横幅广告,我们通过一个叫“Ad Exchanges”的结构接收请求,了解客户愿意支付多少钱。我们收到、处理请求的时候,会给发送端的服务返回响应。这个项目的运营需求是每秒处理四万个查询(QPS),单个交易的往返处理时间不超过一百毫秒。
应用发布到生产环境之后,情况果然非常糟糕,因为我们每秒只能处理五千个查询。而且近30%的交易都失败了,因为我们满足不了一百毫秒的需求。更糟糕的是,性能如此之差却没什么明显的原因。我们搞不清楚问题是源自网络、服务器容量,还是应用层。
最终是度量帮我们找出了问题的真正原因,并扭转了局面。我们每秒能处理的查询最终有七万多个(比一开始多十四倍多),同时能保证失败交易数低于0.5%(大概比原来低五十倍)。但为了实现这样的结果,我们对数据进行了更多分析和结构化处理,在接下来的章节中我们继续说明。
分层的指标
由于在RTB项目开始的时候我们已经有一个度量项目了,所以我们就在RTB应用里嵌入了一些指标。而且我们已经有针对服务器和网络方面的度量。但在数据的海洋里很难辨别出必要的数据、了解趋势,并找出我们的性能远远低于要求阈值的原因。很显然,仅仅有数据并不会带来多大的价值。
所以我们决定在三个层面对数据进行可视化:
- 业务指标
- 应用指标
- 基础设施指标
分层的方法让度量更加结构化了,对所有人(从开发人员到业务人员)来说都变得可用、易于理解。Business Dashboard成为检查应用状态的公共入口点。任何人都可以访问它,检查当前的状况是否符合要求的SLA、使用趋势或收入。如果需要的话,大家还可以深入到Application Dashboard去检查不同应用组件的性能、不同服务器组的延迟及数据增长。事实上,Application Dashboard上的一些指标在Business Dashboard上也有,只是更为详细。举例来说,我们在Business Dashboard上绘制了应用性能,在Application Dashboard上则绘制了应用不同部分的执行情况(见图1和图2)。最后,我们在Infrastructure Dashboard上检查关于CPU、内存和I/O使用率的相关信息。
(点击图片查看大图)
图1. Business Dashboard上的应用性能
(点击图片查看大图)
图2. Application Dashboard上的应用性能
要找出问题的根本原因(不仅仅是看结果),接下来要做的就是把不同的指标关联起来。我们把显示关键指标的图形叠加了起来,从上到下依次是业务指标、应用指标和基础设施指标。这种方法有两种用途。我们从上往下看这些图形的时候,可以清楚地看到QPS的变化是怎样影响应用性能和服务器CPU的(参见图3)。相反,从下往上看的时候,则可以看出I/O的增加是如何影响SLA的。
(点击图片查看大图)
图3. 关联的指标示例(自上往下依次是:QPS、SLA、竞拍服务的性能、CPU负荷)
分层和可用的指标能让开发人员了解项目业务方面的内容。事实上他们能看到我们从哪里赚了多少钱。当新特性或Bug修复发布到生产环境里后,开发人员立即就能在Business Dashboard的金钱图标里看到这些内容对收益产生了怎样的影响。反过来,业务人员也能理解项目技术方面的内容,看到开发人员所面临的问题和我们的负载局限。在现实中,我们还根据度量设置了目标,借此把MDD嵌入到了Scrum里。最终,参与项目的所有人员都对项目的各个部分都有了认识,结果很圆满。
利用度量做决策
在任何活动里,最重要的事情都是认识和理解目标及其背后的原因。你可以创建不同的Dashboard、收集大量度量数据,但如果不作为决策的输入,度量就没什么用处。我见过好几个例子,都是团队创建了多个度量项,但大家却不理解度量的含义和必须设置的原因。所以他们也没利用度量指导决策。还有一个不好的例子,团队做决策时甚至不知道他们的应用到底是怎么运行的(我宁愿说这是我猜的)。他们有一些指标,但还不足以从中获取价值。
MDD的美妙之处在于,它还能最低限度地减少误解。当基于度量做决策的时候,几乎不需要任何解释。决定变得明确、有逻辑、易于阐述,因此也就不易被反驳。决定做得更快更准确,团队的气氛也好转了很多。此外,这也能带来跨团队边界的级联效应。团队间的沟通更多由数据驱动,不再那么情绪化了。换句话说,开发团队和运维团队之间、多个开发团队之间以前会相互指责,这种情况现在则很少发生,甚至完全消失了。
需要注意的是,在某些情况下我们可能从现有的度量里找不到证据,只会去猜问题的真正原因。解决办法是再创建一些指标,来支持或否定最初的假设。
在决策过程中使用度量对大家来说是一个双赢的局面。MDD的主要目标是提供基础设施和应用各个方面的信息,除此以外,MDD还有助于改进团队内部和团队间的关系。
我们学到了什么
我们走了很长的路才在整个组织里应用了MDD实践。这不仅仅是技术的变化,更重要的是文化上的改变。每个人都需要转换观念、态度、对开发过程的理解。在达成愿景的过程中,我们发现了不同的结果。因此,我想和大家分享两个对你可能有益的经验教训。
我们学到的第一个重要经验是,你应该尽全力为开发团队创造尽可能顺利的体验,避免充当中间人。我们最初尝试的解决方案是让运维团队和开发团队共用一个度量服务器。但效果并不理想,对我们来说主要原因有两个。第一,开发团队受制于运维团队,开发团队做的每个修改都需要运维团队的授权。第二,运维团队不喜欢开发团队频繁修改内容。所以我们决定给开发团队专门提供一台服务器,让他们从中获取所有服务器相关的度量信息。开发人员在那台服务器上修改内容不需要按发布过程执行,也不需要特殊的授权。事实上,他们可以在这台服务器上做几乎所有的事情——甚至从监控里删除其他服务器。尽管让开发人员自由去决定、实施并负责变更看起来有些匪夷所思,但这确实是我们做过的最好的决定之一。
第二个非常实用的经验是,我们花费时间去写“监控愿景”或“监控工具的需求”,但都是浪费时间,因为我们的期望和实现在整个过程中变更了好几次。而且它们会继续变化。花费过多的时间去选择一个度量工具也是一种浪费。没有工具能满足你所有的需求,所以挑一个你用着顺手、适合你们愿景和公司的就可以了。我们选择了Zabbix——一个开源工具。尽管它有一些局限,而且导航复杂(我们甚至称它为“一点就死的工具”),但它能让我们迅速开始。最后,别忘了给最常见的用例准备几个收集数据、图形化展示数据的例子。
让MDD变得有趣些,而且让大家都能看到。把显示重要指标的电视放在门厅或工作空间里。如果可能,图形化显示不同项目的收益。给一定的成就设置奖励,比如连续成功发布的次数(参见图4)。大家一起度量最好的成绩,比如每天、每周、每月最高的访问量或交易数,并一起为之庆祝。这种方法会引发大家的好奇心,让大家提出问题,并参与到度量里来。通常情况下,你可以从添加一些简单的图形开始。同事们在门厅看到后,会立即提出一些很棒的改进意见。
(点击图片查看大图)
图4. 成功发布的奖励
对参与MDD的所有团队来说,尤其是对开发人员来说,MDD要求的文化变化还是很冒险的。他们开始用自己的应用来观察问题,之前大家都不了解这种做法。Adform的思维模式完全发生了变化。原来的态度是,只要没人抱怨,就认为一切都正常。现在,所有人都知道这不是度量应用性能的好办法。开发人员现在都能很自如地处理度量了。出乎意料的是,开发团队原先看不到度量信息,对自己的应用倒是感觉良好,而现在只要指标不可用,他们就会觉得不舒服。
目前的工作重点和未来计划
我们要在整个组织里推行MDD,新的挑战会随之不断出现。当多个团队有不同的需要、愿景、对度量的理解,却在一起创建指标的时候,事情就会变得很混乱。我们要定期删除不用的指标,并以类似的方式让度量覆盖到新项目。
目前,我们正试着为开发人员创建准则,以确保所有开发人员达成共识。每个开发团队都要能回答下面三个问题:
- 你怎么知道你的应用运行正常?(Bug少并不够,必须提供进一步的证据,比如模拟)
- 应用的性能随着时间的推移会有怎样的表现?(比如说,和上一个版本相比,它是越来越快还是越来越慢?在高负载情况下是否仍能良好运行?)
- 你的应用的使用频率是多少?(比如有多少用户会在同一时间去生成报告?系统在白天会发布多少横幅广告?我们收到多少笔交易?)
这些问题有助于确保所有的应用在进入生产环境前都能被度量,并达到相同的度量覆盖水平。
至于以后的改进,我们现在正在做一个交通信号灯监控层(为了获得更快的反馈,最终达到外包一级响应等级——参见图5),还有度量驱动的硬件容量评估。
(点击图片查看大图)
图5. 应用信号灯
总之,把度量加到开发过程里有很大的潜力。在整个组织内推行这种实践是很难的。但潜在的好处也很巨大:应用和业务表现对开发团队和业务人员来说是可见的,大家可以基于真实的数据更快、更准确地做决定,而且团队内和团队间的沟通也能得到提升。