写点什么

减少技术债务的系统方法

作者:俞凡
  • 2022 年 1 月 22 日
  • 本文字数:4425 字

    阅读完需:约 15 分钟

技术债务是所有技术团队都会面临的问题,这篇文章介绍了德国电商巨头 Zalando 如何通过管理和流程的优化解决技术债务的问题,从而帮助团队提升工作满意度并且有效减少技术债务的积压。原文:A Systematic Approach to Reducing Technical Debt[1]


本文从工程管理的角度阐述怎样通过系统的方法减少技术债务,介绍了我们的一个核心工程团队是怎样建立并实践了这一方法,并且说明了如何有效的将这样的工作资本化。

简介


技术债务在软件工程中是一个很常见的问题,由于缺乏明确定义的流程,技术债务或多或少只会累积起来,但 Zalando Direct 内部的 Merchant Orders 团队的情况是一个例外。当我在 2020 年秋季加入这个团队,成为新任工程主管时,积压的技术债务甚至可以追溯到 2018 年。在本文中,我将描述我们在 2021 年第一季度建立的流程,以重新获得对技术债务的控制。虽然你自己团队的情况可能没有那么可怕,但你可能会发现这篇文章的某些方面还是有用的。我们积压的技术债务工单曾经超过 70 张,而且还在不断增加。通过采用本文描述的方法,我们已经在 8 周的时间(也就是 4 个 Sprint)里发布了超过 10 个特性或改进,这是三年来(或者说自从我的团队开始跟踪技术债务以来)第一次减少了技术债务。


这篇文章是从管理的角度写的,目标读者是工程师和工程经理,不过我希望所有级别的工程师都能在这篇文章中发现价值。此外,如果不断增长的技术债务已经成为团队的问题,我鼓励阅读这篇文章的软件工程师可以跟领导就这一问题进行沟通。如果所有人都意识到技术债务是一个严重的问题,他们很有可能会感激你提出这个问题并跟他们讨论。如果我们不为当前的技术债务付出代价,就会积累越来越多的技术债务,直到完全重写系统成为了唯一的选择。这与现实世界中让债务人破产的复利非常相似,显然我们都希望避免这种结果发生。


这是我的团队截至 2021 年 4 月积压的技术债务的摘录。如你所见,上面有 2018 年和 2019 年的条目。

技术债务,已知的和未知的


基于乔哈里窗[2]词汇表,我们也许可以在代码库中识别出大量“已知(known known)”的技术债务。在我们的例子中,积压了大量已知技术债务。考虑到我们有十几项服务需要维护,这个数字可能还不是特别可怕。然而,还有大量“未知的(unknown unknown)”技术债务,即那些我们还不知道、不认识、完全没有意识到的技术债务。这似乎有点违反直觉,因为你可能会认为我们已经能够预先完美、一劳永逸的设计服务。不过,考虑到我们可能会遇到持有类似信念的非技术领导者,这并非完全不可能,甚至在某些情况下,这是完全可以预期的。


至少有两个未知技术债务的来源。首先,我们的服务可能存在一些还没有发现的问题。这很常见,因为一旦我们做出了某个设计,可能没有人会质疑团队达成一致的任何决定。当然,我们的设计或实现中可能存在缺陷,只有通过新的角度(例如新加入的团队成员)才有可能发现这些缺陷。第二,技术是一个快速发展的领域,意味着今天的流行设计模式、开发过程、测试策略,甚至编程语言和范式都可能会被取代。当前的最佳实践取代了之前的最佳实践,并且某些新的发展方向会让我们对那些迄今为止有效的方法产生怀疑。当然,我们有时候需要快速交付特性以抓住业务机会,这也可能会导致设计和实现决策不佳。


然而,并非所有的改变都是积极的。尽管工程师可能会为自己的客观性感到自豪,但这一行业也受到流行的驱动。这是很大的问题,Gardner 这样的公司靠出售他们对某些技术处于的“炒作周期”[3]的分析来赚钱。有时候,作为一个行业,我们也会退步,比如采用一些虽然流行但不那么强大的技术。然而,如果它们是由每年有数亿美元营销预算的公司推动的,就可以在行业中获得很大的吸引力。今天,如果我们的任何一项服务被重写,都可能会有很大的不同。实际的结果是,我认为应该花时间重新审视现有的服务并寻找改进。如果可能的话,对当前流行的技术抱持批判性的观点。即使是 TeX[4](第一个版本在大约 20 年前发布),这可以说是世界上最成熟的软件产品之一,直到今天也仍然需要不断修复。考虑到这一点,我们的服务当然也需要被改进。与此同时,Zalando 在技术选型以及新技术导入方面有正式的流程[5],这当然有助于工程领导者,但不能解决某些技术由于自身的缺点而逐渐失宠的问题。


当我们在一个客户需求和技术都可能变化的高度动态的环境中创建软件解决方案时,对我们的服务进行半定期的检查可能会发现需要改进的地方。所有这些都应该被归类为(迄今为止未知的)技术债务。这种练习可以导致一个非常受欢迎的结果:工程师将更加熟悉他们的服务。如果我们的服务需要在任何时候能够可靠工作,那么这一点尤为重要。每个随叫随到的工程师最好都对服务有非常详细的了解,彻底研究现有服务的源代码将对他们非常有帮助。

激励工程师


在管理理论中有一个流行的概念,X 理论/Y 理论,这两个理论是成对出现的。根据 X 理论,人们工作只是因为需要钱,如果可以的话,他们宁愿根本不工作。相比之下,Y 理论认为人们是有内在动机的,关心自己的工作,并希望在职业生涯中取得进步。现实可能介于两者之间。然而作为领导者,问题是如何让人们愿意为技术债务工作。在我们的案例中,问题在于那些积压了 3 年的技术债务工单,这似乎意味着缺少解决此类工单的动力。


作为领导者,我们当然可以简单的告诉人们该做什么(X 理论)。但问题是,如果人们工作是为了内心真正想做的(Y 理论),往往会更有效率。此外,作为工程师,我的经验是,技术债的工作既可以让人感到满足,也可以打开新的机会。因此,我对团队使用 Y 理论的方法,强调这种工作的好处。请注意,这绝不是胡说八道。作为工程师,我的成长很大程度上有赖于解决棘手的技术问题,通常是专注于性能改进。比如在一次实习中,我的任务是提高人工神经网络的性能,这项工作使我后来进入了一个竞争非常激烈的领域。我还向团队强调,技术债务有时可以很容易量化。工程师的简历上如果有性能提高或内存开销减少百分比的硬数据,肯定会更好看。例如:“通过评估资源需求,每周 AWS 托管费减少了 500 美元”(这是我们工作的实际结果)或“通过优化数据类型和删除冗余信息,我们的数据库空间需求减少了 12%。”

技术债务迭代


我的团队已经安排了几种迭代,因此,我把对技术债务的处理设置为另一个迭代。我的目标是让团队在工作中拥有自主权,所以我建议:所有的工程师轮流进行技术债务迭代,一次迭代持续一周。实际上,这意味着工程师应该在每周一花一些时间来确定他们想要处理的技术债务,可以是已知的技术债务,即来自技术债务跟踪系统的一张或多张工单,也可以是未知的技术债务。对于后者,我建议选择众多服务中的一个,研究源代码,并寻找改进点,这应该会产生一些额外的工单,最好由一名已经发现现有服务可能被改进的工程师负责这项工作。


我希望负责技术债务迭代的工程师在处理常规工单之前,先处理与技术债务相关的工单,当然这需要在计划会议中讨论并评估。我希望参与迭代的工程师至少花一天时间处理技术债务。然而,在某些情况下,特别是对于重要的子项目来说,我们需要做出承诺。也许你没有注意,我并没有解决紧急问题,因为显然并非所有技术债务都是平等的。我们倾向于尽快解决紧迫的问题,甚至不会将其归类为技术债务,而是将其归类为必要的 bug 修复或“运维”问题。尽管如此,我们积累的一些技术债务只是“锦上添花”。我给其他领导的建议是,通过跟踪团队的技术债务记录,密切关注团队正在做什么,需要对问题重要性进行排序,如果还没做,最好先在某个单独的待办事项细化会议上确定这些技术债务的重要性。但处于前面部分所提到的原因,我不建议将技术债务工单按紧急程度排序,并简单分配给工程师。


我们有一个简单的系统对技术债务进行分类,使用两个指标“复杂性”和“影响”,并在 1 到 5 的范围内对两者进行排名。在我们的例子中,这些估计最初是由向技术债务工单中添加条目的工程师完成的,但是他们会周期性的进行审查。我认为可以选择一些容易实现的目标作为开始,例如那些复杂性相对较低但影响程度中等到高的工作。你可能也希望鼓励工程师也以中等到高的影响程度处理更复杂的工作。因为你会发现,某些技术债务影响程度很低,不值得在当前时间点解决,甚至不需要被解决,你可以把这些技术债务工单存起来以备不时之需。

技术债务资本化


软件工程领导的职责之一是确保团队完成的工作是有价值的,这意味着我们创建的任何增加数字资产的软件也应该被添加到我们的金融资产中。反过来,这也减少了我们的税收负担。然而,维护工作不能资本化,因为这被认为是一种开销。然而,技术债务工单的集合可以构成一个可以资本化的迷你项目。一个例子是迁移到新的基础设施或进行重大重写,从而提高性能。诚然,将技术债务工单打包到项目中可能是一种过于理想化的场景,不过也是可能的。在我们的团队中,由于过度依赖面向对象的编程结构,最近发现了 Scala 代码库的一些问题。如果我们解决了这些问题,就会有一个更可维护的系统,并且还有可能提高系统性能。类似的,如果你的待办事项足够长,可能能够识别出一组技术债务工单,这可能构成一个小项目。

结论


我们团队遵循本文所述的技术债务迭代已经进行了大约 6 个月,团队的反馈是积极的。其中,工程师们表示,这为他们的工作增添了多样性,他们欣赏这种增加的自主权。当然,后者只会出现在有足够多的技术债务工单可供选择的情况下。在某种程度上,我们有希望显著减少技术债务积压,然后我们将不得不依赖于希望通过深入研究实现细节或改善服务的性能或设计的满意度来更好的理解现有系统的内在动机。从工程主管的角度来看,我的最终目标是尽可能多的偿还技术债务。事实上,技术债务储备的理想规模应该是零,这是一个遥远的目标,但我们已经朝着它迈出了成功的步伐。首先,我想降低积压的增长率,我们在头两周内就实现了这一目标。 如果你管理的技术债务积压只增长了三年,那么看到它不再增长得那么快就已经令人满意了。 下一步是保持工单数量稳定,我们很快就达到了这个目标。 现在,技术债务积压的工单总数可能有史以来第一次实现了下降,团队对此非常高兴。 一年后,我希望能大幅减少技术债务积压。


References:

[1] A Systematic Approach to Reducing Technical Debt: https://engineering.zalando.com/posts/2021/11/technical-debt.html

[2] Johari window: https://en.wikipedia.org/wiki/Johari_window

[3] Gartner Hype Cycle: https://www.gartner.com/en/research/methodologies/gartner-hype-cycle

[4] TeX: https://en.wikipedia.org/wiki/TeX

[5] Technology Choices at Zalando - Updating our Tech Radar Process: https://engineering.zalando.com/posts/2020/07/technology-choices-at-zalando-tech-radar-update.html


你好,我是俞凡,在 Motorola 做过研发,现在在 Mavenir 做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI 等技术始终保持着浓厚的兴趣,平时喜欢阅读、思考,相信持续学习、终身成长,欢迎一起交流学习。微信公众号:DeepNoMind

发布于: 刚刚阅读数: 2
用户头像

俞凡

关注

还未添加个人签名 2017.10.18 加入

俞凡,Mavenir Systems研发总监,关注高可用架构、高性能服务、5G、人工智能、区块链、DevOps、Agile等。公众号:DeepNoMind

评论

发布
暂无评论
减少技术债务的系统方法