Trunk-Based-Development(主干开发TBD)

现代顶尖互联网公司(如 Google, Meta, Netflix)开发模式的核心。**主干开发(Trunk-Based Development, TBD)** 配合 **特性开关(Feature Flags)**,彻底改变了“如何发布软件”的逻辑。详细拆解这套组合拳是如何运作的,以及它为什么被认为是 DevOps 的终极形态。

#status / growing #type / concept

Trunk-Based Development (主干开发TBD)

Overview

  • 主要推崇者: Paul Hammant 以及 Google / Facebook 等巨头。
  • 起源: 随着 CI/CD 的成熟,大厂发现长期的 Feature 分支是“合并地狱”的根源,因此推崇极其激进的合并策略。
  • 核心逻辑:
    • 几乎没有分支: 所有开发者直接在主干(Trunk/Main)上提交代码,或者使用寿命极短(几小时)的临时分支。
    • Feature Flags (特性开关): 未完成的功能代码也合并进主干,但通过代码里的开关(Flag)在生产环境中隐藏起来,直到功能完成才打开。
  • 适用场景: 技术实力极强、自动化测试覆盖率极高、追求极致迭代速度的团队。
  • 优势: 彻底消灭了“合并冲突”,代码集成非常快。

详情

一、 核心矛盾:为什么需要这套模式?

在传统的 Gitflow 模式中,如果一个功能需要开发 10 天:

  1. 你会切出一个 feature 分支。
  2. 憋了 10 天代码,写了几千行。
  3. 第 11 天,你试图合并回 master
  4. 灾难发生: 你发现你的代码和同事这 10 天提交的代码产生了剧烈的合并冲突(Merge Conflict)。解决冲突可能又要花 2 天,而且很容易改错导致 Bug。

主干开发(TBD)的核心思想就是: 绝不要让代码在这个“孤岛”分支上停留太久。


二、 怎么做:主干开发 + 特性开关

这套流程通过三个步骤来实现“既能频繁合并,又不破坏生产环境”。

1. 主干开发的规则 (The Rule)

  • 动作: 开发者必须每天(甚至每几小时)将本地代码合并回主干(Master/Main)。
  • 结果: 主干上时刻都有包含你“写了一半、还没法运行”的代码。
  • 疑问: “那我写了一半的代码合并上去,用户用到了报错怎么办?” -> 这就需要特性开关

2. 特性开关 (The Solution)

Feature Flags(特性开关) 本质上就是一段逻辑判断代码(if/else)。它允许你把新代码“藏”在主干里,只有你允许的人(比如开发者自己)能看到,普通用户依然运行老代码。

伪代码示例:

假设你正在开发一个新的“黑暗模式”页面,但还没做完。

// 代码已经合并到主干 master 了,此时生产环境正在运行这段代码:

const user = getCurrentUser();

// 检查特性开关:是否对当前用户开启了 "dark_mode_v2"?
if (FeatureFlag.isEnabled("dark_mode_v2", user)) {
    // 【新代码路径】
    // 只有开发者或内部测试人员能走到这里
    renderNewDarkModePage(); 
} else {
    // 【旧代码路径】
    // 所有普通用户依然走这里,仿佛新功能根本不存在
    renderOldLightPage(); 
}

3. 部署与发布的解耦 (Decoupling Deployment from Release)

这是这套模式最精髓的概念:

  • 部署 (Deploy): 把代码上传到服务器运行。
  • 发布 (Release): 让用户真正使用到新功能。

在 TBD 模式下:

  1. Day 1: 你写了黑暗模式的头部 UI,还没写完。你加上开关 if(false)部署到生产环境。用户无感知,代码已集成。
  2. Day 2: 你写了底部 UI。继续部署。用户依然无感知。
  3. Day 3: 功能写完了。你在后台管理系统中,把开关配置改为 true(或者只针对 1% 的用户开启)。瞬间发布

三、 进阶玩法:特性开关的强大之处

除了解决合并冲突,特性开关还带来了 Gitflow 做梦都想不到的能力:

1. 金丝雀发布 (Canary Release)

你不需要一次性让 100% 的用户都用新功能。你可以配置开关:

  • “只对公司内部员工开启” -> 生产环境测试(Testing in Production)。
  • “只对 1% 的用户开启” -> 观察报错率。
  • “逐步扩大到 10%, 50%, 100%” -> 灰度发布。

2. 紧急回滚 (Kill Switch)

如果新功能上线后发现严重 Bug(比如导致服务器崩溃):

  • 传统做法: 需要回滚代码版本,重新打包,重新部署,至少耗时 10-30 分钟。
  • TBD 做法: 在后台把开关关掉(改为 false)。耗时 1 秒,服务立即恢复。

3. A/B 测试

你可以让 50% 用户看红色按钮,50% 用户看蓝色按钮,通过开关控制,对比哪个点击率高。


四、 代价是什么?(缺点与风险)

虽然听起来很完美,但 TBD + Feature Flag 对团队要求极高:

1. 代码里的“垃圾” (Technical Debt)

代码里会充斥着大量的 if/else 开关。

  • 风险: 如果功能上线后,你忘记删除这些开关代码,系统会变得极其复杂,难以维护。
  • 要求: 必须有严格的**“开关清理计划”**。一旦功能全量发布且稳定,必须立即回头删除旧代码和开关逻辑。

2. 对自动化测试要求极高

因为大家都在往主干提交代码,只要一个人提交了烂代码,整个团队的开发进度就会被阻塞(Build Failed)。

  • 要求: 必须有完善的 CI(持续集成)流水线,单元测试覆盖率要高,确保烂代码进不去主干。

3. 配置管理的复杂性

当你有 100 个功能同时在开发时,管理这 100 个开关的状态(哪个开,哪个关,哪个对谁开)需要专门的管理平台(如 LaunchDarkly, 或者自研的配置中心)。


五、 总结:Gitflow vs TBD 的本质区别

维度Gitflow (传统)Trunk-Based Development (现代)
代码合并频率低 (几天甚至几周一次)极高 (每天多次)
冲突处理痛苦,是大爆炸式的冲突轻松,冲突在萌芽期就被解决了
如何隔离半成品使用分支隔离使用特性开关隔离
回滚速度慢 (分钟/小时级)秒级 (关闭开关)
适用团队追求稳健、流程较慢的团队追求极致速度、技术能力强的团队 (Google/Meta)

简单来说:如果你想让团队像 Google 一样快速迭代,“主干开发 + 特性开关” 是必经之路;但如果你没有强大的自动化测试做后盾,这套模式可能会变成灾难。

创建于 2025/12/18 更新于 2026/5/27