访问控制 RBAC / ABAC 总览待审核
实例 · feature flag / 灰度

feature flag / 灰度发布:decide 出一个 variant

「先为 10% 用户开启新版结算」「内测账号直接开启,美区暂不开启」—— feature flag 的求值,同样是这个函数: who (用户 + 属性) → 看到哪个 variant。与 HTTPpricing 两个实例一样,它将 policy 略作推广:输出不是 permit/deny, 而是一个 variant (ON/OFF,或 A/B/C);而 targeting 规则从上到下、第一条命中即生效 —— 这正是 05-decidefirst-applicable

who
用户 + 属性
id / country / plan / beta → targeting
what
这个 flag
被开关的功能,如 new-checkout
action
evaluate
页面渲染时求值「该给他看哪版」
when
发布阶段
灰度 % 随时间逐步放量
flag 的求值顺序 (LaunchDarkly 等均采用此模型): 先看 flag 总开关,关闭 → 直接 OFF (kill switch);再看 个体定向 (allowlist:QA/内部账号直接开); 然后 targeting 规则 从上到下,第一条命中就用它的 variant;都没命中 → 进百分比灰度 (按 hash 分桶,命中就 ON);最后落到 default variant (默认值)。每一步都对应 policy 里的一个概念。

flag 求值:targeting 规则 + 个体定向

用户 (who) —— 选预设再改属性

country
plan
beta 内测

🚩 flag 配置 (这就是 policy)

targeting 规则 (从上到下,第一条命中即生效;可单独停用)

30%

求值轨迹 (亮 = 走到这步;高亮 = 决定 variant 的那步)

顺序即优先级 (first-match):Ben (US · pro) —— 规则「美区→OFF」排在规则「Pro→ON」前面, 第一条命中即胜出 → OFF。停用「美区→OFF」这条,规则「Pro→ON」接管 → ON。再选 Cody (US · 内测) —— 规则「内测→ON」位于最前,因此即便他在美区也同样 ON。调换两条规则的顺序,结论可能反转 —— 这就是 first-applicable,与防火墙规则链、05-decide 的算法完全一致。

百分比灰度:确定性分桶,稳定且单调

未被规则命中的用户,进入百分比灰度。关键在于:不能每次随机取值 (否则同一用户时而看到新版、时而看到旧版)。 做法是将 hash(flagKey + ":" + userId) 映射到一个固定的桶 0–99,桶号 < 放量% 即开启。 下面 100 个用户按桶排列,拖动放量滑块即可看到哪些被点亮 (当前用户以黑框标示):

30 / 100 用户开启 放量 30%
为什么这样分桶在工程上可靠:
稳定 (sticky):同一 userId 的桶号始终不变 —— 用户体验一致,不会出现闪烁。
单调 (monotonic):放量从 30% 提升至 50%,只会新增用户进入,已开启的绝不会被关闭 —— 放量始终安全、可回滚。
每个 flag 独立:hash 中包含 flagKey,因此一个用户在 flag A 进入了灰度,在 flag B 未必如此 —— 避免「同一批人覆盖所有实验」。
这实际上为 policy 增加了一种特殊的 who 分组:伪随机,但确定、可复现

feature flag 概念 → policy 概念

flag 里的说法policy 里的概念 (第 01–05 页)
targeting 规则的条件规则条件 when(req) (看 who 的属性 = ABAC)
规则从上到下、第一条命中first-applicable「顺序即优先级」
个体定向 (allowlist)显式 allow 覆盖 (像 RBAC 的 UserAllow)
百分比灰度 (hash 分桶)确定性的 who 分组:伪随机但稳定可复现
default / fallthrough variant默认决策 (没规则命中时的最终取值)
flag 总开关 (kill switch)全局 disable / 一次关闭
variant (ON/OFF 或 A/B/C 多分支)decision 是枚举值,不是布尔 (像 pricing 是个价)
A/B 实验 = 把灰度桶分流到多个 variant 再测指标;本质仍是「who → 哪个分支」。

相关链接