引言
在大型研发团队中,构建效率、IDE 刷新速度和本地开发体验,都会直接影响研发生产力。本文以某海外大型互联网公司的 Gradle 迁移实践为例,介绍其如何从 SBT 迁移到 Gradle,并通过构建系统优化,将大型 Play 应用的构建时间从 60 分钟降至 15 分钟,实现构建效率提升 4 倍。
对于希望系统性提升研发效能的团队来说,构建系统优化只是其中一环。真正可持续的效率提升,还需要将团队目标、需求评审、开发协作、测试验证、发布上线和知识沉淀串联起来。PingCode 这类智能化研发管理工具,能够覆盖研发全生命周期管理,并打通研发过程中使用的多类工具,让研发数据在不同环节之间顺畅流转,从而帮助团队更好地衡量和提升研发效能。

在某海外大型互联网公司,500 多个微服务和 3500 多个 API 端点共同构成了复杂的软件生态系统。这也意味着,公司内部运行着数量庞大的 Web 应用。2012 年,该公司将 Play Framework 引入技术栈,用于构建微服务和 Web 应用。此后,团队陆续创建了 330 多个 Play 应用,每天都有数百名工程师参与这些应用的开发。
其中一个 Play 应用承担着关键服务职责,支撑来自网站和移动客户端的全部 API 流量,每秒处理超过 13 万个请求。
虽然这些 Play 应用在运行指标上表现出色,但团队逐渐发现,开发者满意度和工程效率正在受到影响。仅仅搭建开发环境就要等待一个小时,这显然是一种浪费。某个最大的 Play 应用在 IDE 中的刷新速度也慢得惊人。考虑到每天都有大量工程师参与这个应用的开发,这些等待时间累计起来,相当于数百小时的非生产性构建时间。
IDE 刷新缓慢只是冰山一角。本地开发同样因为热重载速度过慢而变得异常痛苦。原本只需几秒钟完成的操作,后来却需要几分钟。
此外,该公司的工程团队一直追求“3×3”部署目标:每天发布 3 次,并且从代码提交到上线运行的时间不超过 3 小时。但在构建时间过长、开发者生产力下降的情况下,实现这一目标变得十分困难。
生产力下降的原因之一,是构建系统。Play Framework 默认使用 SBT 作为构建系统。SBT 已经服务团队多年,但随着应用规模持续扩大,以及公司整体工程规模不断增长,SBT 开始显得力不从心。因此,团队开始寻找替代方案,并最终决定迁移到 Gradle。
一年后的今天,也就是本文发布时,公司最大的 Play 应用之一,IDE 刷新时间已经缩短到 5 分钟以内,构建时间也从 60 分钟降至 15 分钟。以下就是团队如何实现这一变化的过程。
为什么要迁移构建系统:SBT 的瓶颈开始显现
长期以来,团队一直使用 Play Framework 原生自带的 SBT。随着 Play 应用规模持续增长,一些难以忽视的问题开始出现,并促使团队寻找替代方案。
可扩展性。 对于规模较大的 Play 应用,构建时间可能长达 45 分钟到 1 小时。依赖刷新以及随后的 IDE 配置,也需要同样长的时间。构建系统显然已经成为瓶颈,无法随着代码库规模增长而持续扩展。
生产力。 在一些大型应用中,搭建和更新开发环境需要近一个小时。考虑到参与这些大型应用开发的众多工程师平均每天都要更新一次开发环境,这意味着每天都会损失大量时间,严重影响研发生产力。
可维护性。 该公司主要使用 Java,内部有超过 1 万个用 Java 编写的应用和服务。然而,SBT 的构建脚本使用 Scala 编写。SBT 的语法相对复杂,甚至可以说相当晦涩,大量重载运算符容易让人望而却步,可读性也不够理想。从长期来看,维护这些构建脚本必然会成为挑战。
从 SBT 迁移到 Gradle 的早期探索
截至 2014 年底,该公司已经广泛使用 Gradle 来构建 Java、Android、C/C++ 和 iOS 应用。因此,Gradle 自然被视为替代 SBT 的候选方案之一。随后,团队开始推动 Gradle 对 Play 应用构建的支持。在 2015 年的一篇工程博客中,团队讨论了逐步淘汰 SBT,并将 Gradle 作为 Play 应用主要构建工具的计划。
2015 年,团队首次尝试用 Gradle 替换 SBT,但最终并未成功。所需工作量之大令人望而却步,也阻碍了项目继续推进。当时,除了这家公司之外,几乎没有人认真考虑在 Play 应用中使用 Gradle。社区中也有人发文指出,相关 Gradle Play 插件存在明显缺陷。团队几乎无法借鉴他人的经验,只能自己开路。
长期以来,SBT 与 Play Framework 深度绑定。Play Framework 的文档、最佳实践、插件系统和热重载工作流,都与 SBT 紧密相关。此外,公司内部团队还在 SBT 基础上做了大量构建定制。由于这些原因,“Play on Gradle”项目推进缓慢,压力也越来越大。与此同时,公司的 Play 代码库仍在持续增长,进一步加剧了生产力问题。
2016 年底,团队重启了这一项目,并采用了不同的执行策略。这一次,他们不再纠结于 Play on Gradle 的大量缺陷,而是开始快速迭代,目标是尽快让第一个应用成功上线。
这种类似“创业团队”的推进方式彻底改变了局面。团队迅速识别出优先级最高的问题,并明确哪些问题需要反馈给相关构建工具团队,哪些问题需要反馈给框架维护团队。将使用 Gradle 构建的应用部署到生产环境,为团队提供了真实验证和数据支撑,也帮助项目赢得了更多内部认可。
构建效率提升 4 倍,极大激励了团队成员参与到共同目标中来。2017 年初,第一批应用正式上线,团队规模也随之扩大。项目从早期探索阶段进入真正的执行阶段:每个月都有更多团队完成迁移;与此同时,团队持续改进 Gradle 插件,并清理项目早期积累的技术债务。
Gradle 迁移为什么并不轻松
迁移到 Gradle 是一项历时数个季度的复杂工程。对于数百名受影响的工程师来说,迁移过程必须尽可能平稳,并尽量减少痛苦。
该项目历时两年,从最初只有几名工程师参与,逐渐发展为多个团队共同推进。截至本文撰写时,项目已经接近尾声。大多数重要的 Play 应用已经迁移到 Gradle,剩余少数应用也正在按计划推进,预计将在未来几个月内完成迁移。
这一转型过程之所以艰难,主要有以下几个原因。
代码库仍在活跃开发。 从 SBT 迁移到基于 Gradle 的构建系统时,相关代码库仍处于活跃开发状态。迁移过程必须尽量对正在开发的工程师透明。团队必须确保在迁移过程中,Gradle 和 SBT 能够在同一个应用中共存。这样一来,在添加 Gradle 构建支持的同时,SBT 仍然可以继续工作。这项工作就像是在给一辆行驶中的汽车更换引擎。
应用类型复杂多样。 公司基于 Play Framework 构建了多种类型的应用,例如 UI 前端、中间层和 API 前端等。每种应用都有自身的复杂性和特殊要求。
既有基础设施复杂。 由于公司长期在非 Play 应用中使用 Gradle,迁移过程中需要考虑多个已有 Gradle 插件。为了在 Play 应用中复用这些插件,团队需要对插件进行修复、打补丁或重写,同时还必须保持向后兼容。此外,公司拥有自己的代码库管理系统和内部框架,这也增加了额外复杂性。
构建脚本差异较大。 构建脚本迁移不存在“一刀切”的方案。每个应用都有自己的定制化逻辑,因此有效迁移需要跨组织协作。作为较早采用 Gradle Play 插件的团队之一,该公司也遇到了许多需要修复的问题。条件允许时,团队会先在内部修复这些问题,再向开源项目提交 Pull Request,让更广泛的社区也能受益。
对于这类跨团队迁移项目来说,除了技术方案本身,任务拆解、进度同步、文档沉淀、会议安排和审批流程同样重要。Worktile 这类通用项目协作系统,可以承接任务、项目、文档、即时沟通、目标、日历、甘特图、工时和审批等协作场景,帮助团队降低跨组织推进复杂工程项目时的沟通成本。
总体而言,这是一个复杂的跨组织项目,涉及选择合适的概念验证代码库,与这些代码库的负责人合作了解其构建结构,改进 Play 的 Gradle 插件,并协助各团队迁移其自定义构建脚本。
构建效率提升 4 倍带来了哪些收益
迁移完成后,团队看到了非常显著的成果。
生产力提升。 Gradle 更快的依赖解析速度,显著提升了整体研发生产力。这些生产力提升让团队能够更快地为用户交付功能和修复。此外,一些应用的 IDE 刷新速度提升了 4 到 6 倍。开发者对此非常满意,这一点也在多次内部调查中得到了体现。
构建速度更快。 Gradle 默认支持增量构建,这意味着工程师在本地开发期间通常可以跳过完整构建。根据应用代码规模不同,构建速度提升了 150% 到 400%。每个季度,团队都能在构建生命周期的各个阶段节省超过 1000 小时的工程时间。
可维护性更好。 Gradle 与 Groovy、Java、Kotlin 等 JVM 语言兼容。团队的大部分插件都使用 Java 开发,并能与构建脚本无缝集成。由于 Java 是公司的主要开发语言,这对长期可维护性非常有利。
可扩展性更强。 团队通过增量式任务设计,确保 Play 应用中使用的每个 Gradle 任务都具备必要的可扩展性。例如,通过路径管理 jar 包来处理大型类路径,使构建系统能够随着代码规模增长而更加优雅地扩展。Gradle 还提供了一个优秀平台,让团队可以进一步通过构建缓存扩展构建系统能力。

想让你的 Play 应用也获得类似效果吗?为了帮助社区更好地使用开源 Gradle 插件开发 Play 应用,团队曾在 2017 年参加两场海外技术会议,并分享相关实践。如果你正在开发 Play 应用,并且 Gradle 符合你的需求,不妨考虑使用它。让我们共同努力,让 Play 应用开发体验变得更好。
下一步:通过 Gradle 构建缓存继续优化构建时间
迁移到 Gradle 后,团队得以继续推进其他构建优化。其中最重要的一项是 Gradle 构建缓存。构建缓存的目标,是通过复用其他构建产生的输出来节省时间。
早期构建缓存实验表明,构建时间还能进一步缩短 15% 到 20%。随着团队持续改进,预计在不久的将来,这一数字有望提升至 40%。
文章包含AI辅助创作:Gradle 迁移实践:某海外大型互联网公司如何将构建效率提升 4 倍,发布者:shang,转载请注明出处:https://worktile.com/kb/p/3979666
微信扫一扫
支付宝扫一扫