2. Feature Flag 的应用场景:灰度发布、AB 测试、限流降级、功能试用

Feature Flag 这东西,说白了就是个开关。但我告诉你,开关放哪、怎么拧、拧多大——这里面的门道,比你想象的深得多。我这几年踩过的坑,多半都是没搞明白应用场景就乱上开关。

那咱们今天就聊聊四个最常用的场景。

2.1 灰度发布——先放1%的流量试试水

灰度发布,也叫金丝雀发布。它和全量发布的区别,我用一句话总结:先让一小部分用户“吃螃蟹”,没事再让剩下的人吃。

为什么会需要灰度?你想想看,一个新功能上线,你以为是优化,结果线上炸了怎么办?全量回滚?那得多少用户受影响?

我习惯的灰度策略分三档:

  1. 内部白名单灰度——先让自己团队、测试人员在线上验证
  2. 小比例灰度——比如 1%、5% 的用户
  3. 逐步放量——10%→30%→50%→100%

核心就是用手里的开关,把风险锁死在可控范围内。

举个配置例子:

{
  "feature": "new_checkout_flow",
  "rules": [
    {
      "condition": "user_id % 100 < 5",  // 5% 灰度
      "enabled": true
    },
    {
      "condition": "user_group == 'internal'",
      "enabled": true
    }
  ],
  "default": false
}

注意那个 user_id % 100 < 5。它是一个哈希算法,保证同一个用户每次进来结果一致。这块很容易出错——我曾经见过有人用随机数,结果用户刷一次页面开一次关一次,体验极其糟糕。

⚠️ 避坑指南:灰度发布一定要保证 一致性哈希 或者基于用户身份的稳定标识。别用 Math.random() 做灰度判断,否则用户会疯掉。

2.2 AB 测试——用数据说话,别拍脑袋

AB 测试和灰度发布长得很像,但目的完全不同。灰度是为了验证稳定性,AB 是为了验证效果。

举个例子:你改了一个新按钮颜色,想知道转化率有没有提升。你不能直接全量上线——万一是负优化呢?

AB 测试的核心逻辑是:把用户随机分到实验组和对照组,然后比较关键指标。

我常用的 AB 分析表结构:

分组流量占比实验开关指标定义
对照组 (A)50%off旧按钮点击率
实验组 (B)50%on新按钮点击率

但这里有个坑:分组一定要在服务端或 SDK 层级完成,并且要保持稳定。你不能让同一个用户今天在A组,明天在B组——那样数据就乱了。

我曾经踩过这个坑:一个 AB 实验跑了三天,发现两组数据几乎一样。查了半天,原来是客户端缓存的 Flag 值被清空了,导致用户每次请求都可能重新分桶。后来我改成用用户ID的哈希模10来分桶,才稳定下来。

💡 小技巧:AB 测试建议预留 10% 的流量作为“空跑期”。先不开实验,只打日志。确认日志没毛病再正式开量。这叫“干跑实验”。

2.3 限流降级——把风险挡在门外

限流降级是我 SRE 工作中打交道最多的场景。线上突发的流量尖峰,比如大促、刷屏、爬虫攻击,没有 Feature Flag 你就得紧急改代码重启——那太慢了。

限流降级的 Feature Flag 通常是全局开关:

  • 限流开关:当 QPS 超过阈值,部分请求直接返回降级响应
  • 降级开关:关闭非核心功能,比如关闭“个性化推荐”,只保留搜索

我用过一个经典的配置策略:

{
  "feature": "rate_limit_search",
  "rules": [
    {
      "condition": "qps > 5000",
      "enabled": true
    }
  ],
  "default": false,
  "fallback_action": "return_cached_results"
}

但这里要注意:限流降级的 Flag 评估性能必须极高。你不能在每次请求时都查数据库,那本身就是一种攻击。我建议用本地缓存 + TTL 的方式,把开关值缓存个 1-5 秒。

我记得有一次线上故障:用户投诉首页打不开。查下来是一个降级开关配置错了,把“降级”写成了“关闭所有接口”。嗯,从那以后,我要求所有降级开关配置都要经过 double-check 和自动化测试。

🔑 核心原则:限流降级开关要优先保证 低延迟 和 高可用。建议用独立配置中心,不要和业务代码混在一起。

2.4 功能试用——给 VIP 用户开小灶

功能试用,也叫“内测”或“抢先体验”。它不像灰度那样随机,而是基于用户属性有选择地开放。

常见场景:

  • 企业版用户才能使用“高级报表”功能
  • 内测用户提前体验“AI 绘画”
  • 地域限制:某些功能只对北美区开放

这种场景的 Flag 逻辑通常是:

if isVipUser(user) OR isInWhitelist(user) OR isFeatureTrialEnabledFor(user):
    enableNewFeature()
else:
    useFallback()

为什么会单独把它列出来?因为它和后三种场景有一个本质区别:试用是面向“人”的,不是面向“流量”的。灰度/AB/限流都是面向请求的,而试用是面向用户的身份信息。

我在项目中遇到过这个场景:有个新功能想给头部大客户先体验,结果灰度开关用了简单的随机百分比,大客户没有分到灰度的那组里。客户问“为什么我们要晚两周才能用?”——这就很尴尬了。

所以我建议:功能试用应该走独立的用户属性匹配规则,而不是流量规则。两者可以叠加,但优先级要明确。

💡 我的习惯:在功能试用场景中,我会给每个内测用户打上标签(比如 feature_trial:beta_user),然后在 Flag 规则里直接匹配这个标签。这样比用用户 ID 范围灵活得多。

2.5 四个场景的对比表格

我把这四个场景的核心区别列一下,方便你记忆:

场景目标目标对象典型配置核心风险
灰度发布降低发布风险流量(百分比)user_id % N分组不一致
AB 测试验证效果流量(随机桶)user_id 哈希分桶数据污染
限流降级保护系统请求(QPS)动态阈值 + fallback配置错误 & 性能
功能试用体验 & 反馈用户身份标签 / 白名单误开放 & 越权

你可能会问:这四种场景能不能混在一起用?答案是:可以,但一定要分清楚优先级和规则边界。比如灰度发布期间同时跑 AB 测试——没问题,但需要确保灰度分组和 AB 分组不冲突,否则流量会被截断。

我个人建议先从小场景练起。比如先做一个简单的“功能试用”开关,跑通整个流程:建 Flag → 配置规则 → 打标 → 上线 → 观察 → 下线。把这个闭环跑熟,再去搞灰度或者限流。

Feature Flag 四大应用场景 灰度发布 降低发布风险 AB 测试 验证效果 限流降级 保护系统 功能试用 体验 & 反馈 流量(百分比) user_id % N 流量(随机桶) 哈希分桶 请求(QPS) 动态阈值 用户身份 标签 / 白名单 共用基础设施:配置中心 · 本地缓存 · SDK · 监控 规则引擎 · 一致性哈希 · 漏斗分析 · 降级预案 ⚠️ 分组不一致 用户刷到不同状态 ⚠️ 数据污染 分组不稳定 ⚠️ 配置错误/性能 降级路径有 bug ⚠️ 越权 / 误开放 用户标签错误 核心原则:明确场景 · 稳定分组 · 快速回滚