一个团队准备给功能加开关,通常会先想到平台:控制台、权限、灰度、审计、实时生效,一整套产品看上去比改配置文件体面得多。
但有篇技术博客提出了一个不太讨喜、却很实用的判断:很多团队根本不需要功能开关管理平台。一个放进代码仓库的 JSON 文件,应用启动时读取,改动走正常的评审、测试和部署流程,已经够用。
这件事有意思的地方,在于它反过来追问了一遍“灵活性”的价格。功能开关平台卖的确实是即时控制,但即时控制也会把系统状态、权限边界和排查难度一起带进来。
一个 JSON 文件能解决什么
博客主张的方案很简单:
- 开关配置放在版本控制中。
- 应用启动时读取 JSON。
- 修改通过代码评审。
- 变更经过测试,再随版本部署。
- 使用完成后,删除配置和对应代码。
这里的“硬编码”不能理解成把 if 语句散落在代码各处。它指的是一套受代码仓库管理的简单配置。配置有版本,有提交记录,也能跟代码一起回滚。
对发布频率不高、用户规模有限、没有复杂灰度需求的团队,这条路径有几个现实优势。
开发者知道某个开关来自哪个提交。测试环境和生产环境的差异可以被审查。一次发布包含了代码和配置,问题出现时,排查范围相对清楚。更重要的是,开关不会凭空变成一项长期服务。
这对技术负责人意味着一个具体选择:先把开关当作发布流程的一部分,而不是默认采购一套新的运行时基础设施。团队可以先用 JSON、YAML 或现有配置系统跑起来,等真实需求撞上来,再评估平台。
灵活性背后,是另一套状态系统
LaunchDarkly 这类功能开关平台解决的是另一类问题:代码已经部署,团队仍然希望改变行为。
这在某些场景很有价值。比如只给一小批用户开放功能,按租户切换,做 A/B 测试,发生故障时立即关闭某个路径,或者在多实例服务中统一调整配置。它们都需要运行时控制,单靠重新构建和部署会显得迟钝。
代价也很具体:
| 方案 | 能力 | 主要成本 | 更适合谁 |
|---|---|---|---|
| 版本控制配置 | 简单开关、随版本发布、可审查回滚 | 修改要重新测试和部署 | 小团队、内部系统、发布节奏稳定的产品 |
| 独立开关平台 | 灰度、按用户或租户控制、运行时关闭、权限审计 | 额外服务、状态同步、权限治理、排查复杂度 | 多实例生产系统、频繁灰度、强回滚要求的团队 |
| 散落在代码里的临时开关 | 修改快 | 很难发现、测试和清理 | 不应成为长期方案 |
平台本质上是在独立管理一批 if 语句。代码部署在一边,开关状态在另一边。用户看到的行为,取决于两者当时是否一致。
这会制造非确定性。开发者看到代码后,未必能知道线上开关是什么;日志里出现了异常,也未必能马上判断是代码变更还是远程配置造成的。多实例服务还要处理配置拉取失败、缓存过期、网络不可用和实例之间的短暂不一致。
平台本身并不等于不安全,也不等于难以治理。恰当的权限、审计和变更流程,确实能降低风险。但这些能力需要人维护。谁能改生产开关?紧急关闭是否需要双人审批?开关多久没有使用就自动提醒?配置服务挂掉时,应用采用什么默认值?
买了控制台,问题没有消失,只是换了一个地方继续存在。
还有一个更容易被低估的账单:开关会在产品上线后留下来。临时开关若没有负责人和过期时间,就会逐渐固化。代码库里保留多个互相影响的条件,测试组合开始膨胀,后来接手的人也不敢删。
受版本控制的方案也会产生技术债,但它通常更容易被搜索、评审和删除。平台里的旧开关则可能安静地活着,直到某次排查故障时,团队才发现它仍然影响生产行为。
运行时管理的门槛在哪里
“简单配置优先”不能变成新的教条。真正的分界线不在团队喜欢 JSON 还是控制台,而在开关是否已经成为高频运营工具。
可以用下面几个问题做初筛:
- 是否需要按用户、租户、地域或设备类型逐步放量?
- 是否需要在不重新部署的情况下立刻关闭功能?
- 是否存在多个服务、多个实例共享同一组开关的要求?
- 是否需要产品、客服或值班人员在权限范围内操作?
- 是否需要记录谁在什么时间改了什么,并支持审计?
- 是否正在做 A/B 测试,并且要稳定维持用户分组?
- 发布频率和故障恢复要求,是否已经让重新部署变成明显瓶颈?
如果大部分答案是否定的,JSON 配置加 Git 评审通常更合算。关键是补几条纪律:每个开关写清用途和负责人,配置命名保持统一,测试默认值和异常值,设置预计删除时间,部署前检查配置格式,应用启动时对未知字段和非法值直接报警。
如果团队已经依赖按租户放量、实时熔断或跨服务一致控制,专门平台就有了正当性。此时评估重点也不该停留在“有没有灰度按钮”,而要看平台的失败模式:服务不可用时应用怎么运行,开关变更能否审计,权限能否细分,配置是否能回滚,成本是否随环境和服务数量快速上升。
这对正在评估平台的开发团队,意味着先做一次开关盘点。把现有开关按“发布控制、用户灰度、紧急关闭、实验分组”分类,统计哪些真的需要运行时变化。没有运行时需求的,留在仓库里;确实需要即时控制的,再单独引入平台。
对负责架构和交付流程的技术负责人,动作更直接:不要用未来可能出现的复杂需求,替今天已经存在的简单问题买单。先定义触发门槛,再决定是否采购。否则团队很容易把“以后可能要灰度”变成今天就要维护的系统。
Unix 时代,很多系统行为靠配置文件控制;后来企业软件把配置做成了管理平台,再后来云服务把平台继续拆成更多服务。技术在进步,组织却常常重复同一个动作:把一个本来能被流程解决的问题,提前升级成一个需要专人值守的产品。
这次博客的价值,不在于证明 JSON 永远优于平台。它提醒工程团队,灵活性不是免费的抽象。只有当运行时变化真的频繁、紧急,而且需要多人协作时,平台化才开始抵消它带来的复杂度。
开关的生命周期也必须算进采购决定。上线只是开始,清理才是结束。能随发布流程被看见和删除的开关,技术债还在可控范围;进入独立控制台、长期无人认领的开关,迟早会变成系统里没人敢碰的旧状态。
“天下熙熙,皆为利来。”平台供应商有理由把每个开关都包装成治理能力,团队也有理由为未来购买弹性。真正成熟的架构判断,是把今天的需求和明天的想象分开计价。
