- Published on
基于 DORA 指标的团队绩效优化实践
- Authors
- Name
- 俞凡
想象一下,你的团队终于获得了预算,可以将软件工程师人数翻倍。太棒了!终于可以修复所有漏洞,实现新想法,清理多年来积累的所有技术债务。是不是?等等……先别急。
首先,招聘和引入新的软件工程师需要时间,他们需要学习领域知识,深入技术栈,还要了解团队使用的具体工具,熟悉流程并与同事建立联系。即使一切顺利,也很可能无法在一年内将团队绩效翻倍(参见 布鲁克定律)。
那就把初级工程师换成高级工程师!那就和人力资源部门扯皮吧,他们很可能会给你推荐错误的人。这方法很可能也行不通。优秀的人确实很重要,但正如爱德华·戴明曾说过的,“ 糟糕的制度每次都会打败优秀的人 ”(参见著名的 红珠实验 或 戴明管理方法 第四章])。
Think about it. You somehow reached the state where you are struggling to keep up with all those tasks and bugs, right? What if you manage to add extra resources and in a year all you gain is technical debt accumulating at an even faster rate? 想想吧,也许你不知不觉就进入了跟不上所有任务和 bug 的状态。如果设法增加了额外资源,而一年后得到的只是以更快速度累积的技术债务,怎么办?
在梦想的明年预算会议上
好吧,我们来改进这个系统。但到底需要改进什么?让我们遵循经过验证的持续改进方法。首先,选择对公司重要的以结果为导向的指标。然后,专注于通过逐一解决最具限制性的因素来改进。
本文将分享我们的团队如何在一年内实现软件交付绩效翻倍提升,且不增加额外资源。我们使用 DORA 指标,因为它们能预测组织绩效和幸福感的提升。
DORA 指标
DevOps 研究与评估(DORA,DevOps Research and Assessment)是一个正在进行的研究项目,旨在理解驱动软件交付和运营绩效的能力。DORA 建议使用四个关键指标来预测组织绩效:
部署频率(DF,Deployment frequency):组织多久将代码部署到生产环境?
变更前置时间(LTFC,Lead time for changes):从提交代码到生产部署需要多长时间?
变更失败率(CFR,Change failure rate):生产变更中有多少比例导致服务降级并需要修复?
恢复时间(TTR,Time to restore):当服务事故或影响用户的缺陷发生时,通常需要多长时间恢复服务?
背景
我们金融科技业务团队成立于 2022 年中期,负责财务领域的多个流程。
图1:2023年初的服务状况
所有功能都是五年前作为单体应用的一部分实现的(见图1)。从那以后,大部分后端逻辑都被提取到微服务中。
团队开始跟踪 DF 和 LTFC 指标,并在年初设定了基线。接下来的几个月里,团队进行了一系列改进,到年底使指标实现了双倍提升。
图2:基于 DORA 指标衡量,团队交付指标提升了两倍
这将是一场得不偿失的胜利,虽然提高了发布速度,但却毁掉了质量。遗憾的是,我们发现使用推荐的 DORA 稳定性指标 CFR 和 TTR 时遇到了困难(参见 Incident Metrics in SRE,2022 VOID Report,DORA Metrics Reference)。相反,团队采用了可靠性指标和未完成缺陷数量,后者需要追踪影响众多用户的重大事件,前者旨在考虑可靠性指标未能涵盖的个别客户问题。
后端服务
三月份的时候,后端服务的 DF 是每月 15 次,LTFC 大约是 14 小时。后者意味着软件工程师通常需要等待将近一天才能将变更部署到生产环境中。这表明开发者体验不佳,市场投入时间较长。
图3:后端服务的统计数据和主要改进已实现。
主要问题是代码不容易理解和修改。如果报告了 bug,诊断、修复并部署到生产环境需要数周时间。单元测试覆盖率较低,团队缺乏信心,大家都不愿意做任何改进,担心会以意想不到的方式破坏代码。
测试自动化、文档和内部质量看起来是最受限制的因素,团队决定开始测量和改进这些数据。
团队采用童子军规则,通过重构和测试自动化来提升代码质量,同时不中断功能开发工作。在实施变更或修复缺陷的同时,也要努力改进代码。不需要巨大的改善,可能只是简单到给修改的类添加单元测试,或者做一些小的重构来对抗代码异味。
我们发现童子军规则让重构效率大幅提升。首先,改进刚完成的代码所需时间更少。其次,更有可能改进那些经常被修改的代码。
童子军规则
“总是让露营地比你来时更干净。”如果发现地上脏乱,不管是谁弄的,都要清理干净,你有义务为下一批营员改善环境。—— 罗伯特·C·马丁
遗憾的是,要精通重构,仅仅阅读大师们的经典著作(例如 重构,代码整洁之道,重构与模式,Five Lines of Code)是不够的。重构技能需要花时间学习并经常练习,才能变得精通。在实际任务中练习重构非常困难,因为经常面临时间压力,而且实际代码更为复杂。于是团队开始练习重构技巧,以获得更多实际作经验来应对代码异味,并且这么做也有助于测试想法。
“怎么成为全明星运动员?显然,体能和天赋很重要。但伟大的运动员每天都花无数小时练习“ —— CodeKata。
到了六月,代码审查显然是最大的瓶颈。合并请求(MR)通常规模较大,在代码审查过程中处理它们既困难又耗时,是一项痛苦且不受欢迎的任务。改善的方法是采用小批量作业(即支持小批量 MR),并同意将代码审查列为优先事项。因此,团队在 7 月份看到代码审查时间大幅减少。
7月,测试覆盖率的提升使团队能够在几乎无需手动进行回归测试的情况下部署到生产环境。此时,部署过程平均耗时 40 分钟,需要许多手动步骤,包括两次金丝雀部署和验证。根据观察和统计,这些手动步骤都是多余的。例如,过去在金丝雀部署期间没有出现任何问题。如果是这样,为什么要在这些事情上面花时间?
尽管过去没人这样做过(至少在我们部门是这样),团队还是决定采用自动化部署。想法是让 MR 合并到主干后直接部署到生产环境,无需人工验证。显而易见的担忧是这会影响质量。不过从另一方面来说,团队也有不错的安全保障:良好的测试自动化、同行代码评审、小批量修改等等。
团队决定尝试一下。如果出现任何问题,借助质量相关指标,也可以及时发现,并回归传统的“安全”程序。幸运的是,这一变化没有影响质量,但将部署时间从 40 分钟缩短到了 4 分钟。DF 和 LTFC 指标也反映了改进,8 月的部署次数提升至每月 43 次,而前置时间为 1.3 小时。
如果一遍又一遍做同样的事情,结果也是一样
总体来看,DF 从三月的 15 小时提升到十月的每月 37 小时,LTFC 的前置时间从三月的 13.8 小时降至十月的 4.2 小时。
UI 页面
单体的紧密耦合和部署工具是无法绕过的问题。每月部署 6 至 8 次的 DF 和 2 至 3 天的 LTFC 导致开发表现和体验不佳。工程师们被激励批量提交,尽量避免部署。公司推荐的解决方案是将页面迁移到微前端(MFE)技术。
图5:UI 页面统计数据。MFE 迁移项目于 8 月完成,导致了更高的 DF 和更低的 LTFC。MFE 的 MR 审查流程变更导致 LTFC 在 10 月及之后有所改善
团队启动了几个重要页面的迁移项目。
微前端,MFE
微前端是一种前端网页开发模式,单个应用可以由不同的构建组成,类似于微服务方法,但针对用 JavaScript 编写的客户端单页应用,是为多个前端应用进行分解和路由的解决方案(维基百科)
新的 MFE 页面于九月推送给所有用户。团队发现性能有所提升,然而当天的 LTFC 和预期相差很远。当我们收集统计数据时,那一刻简直是当头一棒。经过这么多努力,仍然需要等待很长时间才能将更改提交到生产环境!怎么回事?
当团队发现 MFE 迁移未能带来预期的性能提升时
我们需要查看过去一个月所有 MR 数据。对于每个 MR,我们在提交时记录了统计数据,进行了评论、批准、合并和部署。
事实证明,MFE 申请的 MR 审核流程比平时更复杂。例如,需要团队外部的 MFE 社区专家的批准。因此,MR 批准的平均时间为 17.1 小时。
我们联系了 MFE 专家社区,讨论如何优化流程。实施了几项优化,将获批的平均时间缩短到 8 分钟(是的,没错,因为我们有很多小型 MR)。随着审批时间缩短,我们也同意尽量不批量部署,使得部署时间缩短至 1 小时。
因此,10 月的 LTFC 缩短至 14 小时,这是一大进步,被视为显著的绩效提升。
结果与观察
如图2所示,上述所有变化使团队的软件交付绩效实现了双重提升。其中一些需要大量开发工作,还有许多项目需要改变团队的工作方式,但不需要太多工作。其中一些变化需要转变心态或者培养新技能。这些都不需要额外资源。
所有努力最重要的成果是开启了一种新的工作方式 —— 注重内部质量和实验。如果软件工程师发现代码异味,直接修复通常比管理额外技术债务更容易。团队现在可以验证最重要的决策,无需将其与其他低优先级决策批量处理。
管理、协调和沟通也变得更容易。首先,因为尚未部署的代码较少。比如,软件工程师可以和 UX 设计师一起,随时做一些小改动,几分钟内就能完成所有事情,无需任何文件和管理,所需的资源更少。
当你能在几小时内看到成果,而不是几天时,工作时会更有成就感!
有人可能会说,软件交付虽然重要,但只是价值流中的一小部分,因此我们可能并没有为公司带来太大改变。说得有道理。然而,破窗理论在这里同样适用:如果我们改进软件交付,也会鼓励他人进行改进。如果项目经理要等一个月才能向客户交付有意义的东西,怎么会考虑快速实验呢?
要点
通过增加资源来提升绩效相当困难,很可能团队的困难状态正是因为组织内部的运作方式,而这才是最大的改进潜力所在。
推动改进的有效方式如下。首先,选择对公司重要的以结果为导向的指标。然后,专注于通过逐一解决最限制因素来改进。
所有变革的结果是,开启了一种新的工作方式 —— 注重内部质量和实验。
团队必须专注于长期可持续的绩效,而非短期收益。通过采用部分实践,改进时可以不阻碍功能开发。
有效的方法足够通用,也能适用于许多其他团队,只不过每种情况中的最大限制因素可能不一样。