本文以某海外大型互联网公司的发布工程实践为例介绍其如何通过主干发布、准连续发布、持续交付和移动端 CI/CD 体系在大规模工程团队中提升代码交付效率、降低发布风险并持续改善用户体验。随着时间推移软件行业已经形成了多种更快、更安全、更高质量地交付代码的方法。这些实践大多围绕持续集成、持续交付、敏捷开发、DevOps 和测试驱动开发等理念展开。它们共同指向同一个目标让开发者能够以安全、小步、增量的方式快速且正确地将代码交付给用户。某海外大型互联网公司的开发与部署流程是在长期实践中自然演进出来的。它吸收了许多快速迭代方法中的关键技术但并不严格遵循某一种固定方法论。这种灵活而务实的方式使团队能够持续、快速、可靠地发布 Web 和移动端产品。多年来该公司一直采用简单的主干分支与发布分支策略每天三次发布前端代码。工程师可以申请将主干分支中已经通过一系列自动化测试的变更选择性合并到当天的发布分支中也就是进行 cherry-pick。通常情况下团队每天会收到 500 到 700 个 cherry-pick 请求。每周发布团队还会创建一个新的发布分支将当周尚未被 cherry-pick 的所有变更统一纳入其中。这套系统曾经具备很强的扩展性。从 2007 年最初只有几名工程师到后来支撑数千名工程师协作它始终保持稳定运转。好消息是随着工程师人数增长整体产出也在同步提升——代码交付速度基本能够跟上团队规模的扩大。然而除了现有工具和自动化系统之外每日和每周的代码发布仍然需要发布工程师投入一定人力才能确保流程顺利完成。团队逐渐意识到随着规模继续扩大以越来越大的批次交付代码将无法长期支撑业务发展。到 2016 年分支加选择性合并的模式已经接近极限。每天合入主干分支的变更超过 1000 个每周发布的变更数量有时甚至高达 10000 个。协调并发布如此大规模的版本所需的人力投入已经变得难以持续。2016 年 4 月该公司决定将其核心 Web 产品迁移到一种准连续的“从主干发布”系统。在接下来的一年里团队逐步推进这一系统的落地先覆盖 50% 的员工再逐步扩大到 0.1%、1% 和 10% 的生产流量。每一次扩大范围都是一次检验工具和流程能否承受更高发布频率的机会同时也让团队获得真实环境中的反馈。主要目标是确保新系统能够改善用户体验至少不能让用户体验变差。经过近一年的规划与建设到 2017 年 4 月团队只用了三天时间就让所有生产服务器都能够运行直接从主干部署的代码。规模化持续交付从主干分支快速发布真正意义上的持续发布系统会在每一次变更完成后立即将其部署到生产环境。但由于代码迭代速度非常快该公司需要构建一种每隔几个小时发布数十到数百个变更的系统。在这种准持续交付模式下变更通常更小、更具增量性也很少会对真实用户体验产生明显影响。每个版本都会在数小时内分阶段部署到 100% 的生产环境这样一旦发现问题团队就可以及时暂停发布。首先已经通过一系列内部自动化测试并合入主干的变更会先推送给公司员工使用。在这一阶段如果某个变更引入了回归问题系统会触发阻断发布的告警发布团队也可以通过紧急停止机制阻止该版本继续向外发布。若一切正常变更会被推送到 2% 的生产环境。在这个范围内系统会继续收集信号并监控告警尤其关注自动化测试或员工内部测试可能遗漏的边界情况。最后变更会被部署到 100% 的生产环境。此时用户反馈聚合工具会汇总用户报告并在发现异常时发出提醒。许多变更最初都会由灰度开关系统控制。借助这一机制团队可以将移动端和 Web 端代码发布与新功能正式上线解耦从而降低某次特定更新引发问题的风险。如果确实发现问题团队可以直接关闭对应的灰度开关而不必回滚到旧版本或立即提交修复。这种准连续发布周期带来了多方面优势。首先它几乎消除了紧急修复的需求。在过去每天三次发布的系统中如果某个关键变更必须上线但又不在既定发布时间窗口内就需要有人申请紧急修复。这类计划外发布往往会造成干扰因为它们通常需要人工介入并且可能与下一次计划发布发生冲突。而在新系统中绝大多数原本需要紧急修复的内容都可以直接提交到主干并随下一个版本自然发布。其次它能更好地支持全球化工程团队。过去团队曾尝试安排每天三次发布以尽量兼顾世界各地工程办公室的工作时间。但即便如此每周一次的大版本发布仍然要求所有工程师在特定日期和时间集中投入精力而这并不总是符合他们所在时区的工作节奏。新的准连续发布系统意味着全球各地的工程师都可以在最适合自己的时间开发并交付代码。第三它推动团队建设下一代工具、自动化流程和底层系统以支撑公司继续规模化发展。此类项目本质上是对大量团队和系统的一次压力测试。团队改进了发布工具、代码评审工具、测试基础设施、容量管理系统、流量路由系统以及许多其他关键环节。对希望提升研发效能的企业而言类似能力的建设也离不开研发管理与协作工具的支撑例如借助PingCode打通从目标、需求、开发、测试到发布上线的全生命周期管理并通过Worktile承载跨团队任务协作、项目排期、文档沉淀和进度跟踪让研发数据和协作信息在同一流程中持续流转。所有相关团队共同协作推动加快发布周期这一核心项目取得成功。这些改进也将帮助公司为未来增长做好准备。最后它能更快、更好地改善用户体验。过去如果工程师需要等待数天甚至数周才能看到代码在线上运行的效果那么在反馈到来之前他们很可能已经开始开发其他功能。而在持续交付模式下工程师不再需要等待一周甚至更久才能获得关于自己变更的反馈。他们可以更快地发现哪些功能存在问题也可以在改进准备就绪后立即发布而不必等到下一个大型版本窗口。从基础设施角度来看这套新系统也让团队能够更好地应对可能影响用户的罕见事件。最终它拉近了工程师与用户之间的距离同时提升了产品开发效率和产品可靠性。移动端持续交付将 CI/CD 引入移动开发Web 端之所以能够演进到准连续发布系统部分原因在于团队掌控了完整技术栈可以构建或改进实现这一目标所需的工具。而在移动平台上发布产品则面临更大挑战因为现有许多移动开发和部署工具都难以很好地支持快速迭代。为改善这一状况该公司构建并开源了一系列面向快速移动开发的工具包括集成开发环境、构建系统、代码评审工具、移动端基础库、跨平台开发框架和静态分析工具等。这些构建与测试工具共同构成了移动技术栈使团队能够编写高质量代码并将其快速部署到移动平台。移动端持续集成体系分为三层构建、静态分析和测试。每当开发分支中的代码提交到移动端主干分支时系统首先会在所有可能受影响的产品上进行构建。对于移动端来说这意味着每次提交都会触发多款核心应用的构建。团队还会为每个产品构建多个版本以确保覆盖所有支持的芯片架构和模拟器环境。在构建过程中系统会运行代码检查工具和静态分析工具。这些工具可以帮助捕获空指针异常、资源泄漏、内存泄漏、未使用变量以及有风险的系统调用同时也会标记违反内部编码规范的问题。第三个并行运行的系统是移动端自动化测试。它包含数千个单元测试、集成测试和端到端测试并由多种测试框架和自动化工具驱动执行。这套构建和测试流程不仅会在每次提交时运行也会在任何代码变更的整个生命周期中多次运行。仅在某一主流移动平台上团队每天就要执行 5 万到 6 万次构建。通过将传统持续交付技术应用到移动技术栈团队已经将发布周期从四周缩短到两周再进一步缩短到一周。如今移动端仍采用类似 Web 端早期使用的分支加 cherry-pick 模型。虽然团队每周只向生产环境发布一次移动端版本但尽早在真实环境中测试代码仍然至关重要因为这能让工程师更快获得反馈。为此团队每天都会向 Canary 用户提供移动端候选版本其中包括约 100 万名 Beta 测试用户。与此同时随着发布频率不断提高移动工程团队的规模也扩大了 15 倍代码交付速度显著提升。尽管如此2012 年至 2016 年的数据显示无论以代码推送行数还是推送次数衡量移动端工程师的生产力都保持稳定。同样移动版本发布后出现的关键问题数量几乎与部署次数没有直接关系。这说明在规模持续扩大的同时代码质量并没有受到影响。随着持续交付、发布工程和移动端 CI/CD 工具体系不断进步现在正是投身发布工程领域的绝佳时机。该公司多个团队通力协作打造出了一套业界领先的大规模 Web 与移动端部署系统。这一切能够实现部分原因在于公司拥有一支强大的中央发布工程团队他们在基础设施工程中发挥着至关重要的作用。未来发布团队将继续推进各项举措持续改进面向开发者和用户的发布流程同时也会继续分享相关经验、工具和最佳实践。