特性开关与渐进交付工具
新结算逻辑已经随应用版本部署到所有实例,产品经理只给内部员工打开开关。几分钟后,部分普通用户也看到了新入口;团队紧急关闭控制台里的 flag,错误率却没有立刻下降。排查才发现,Web 端使用邮箱做 targeting,服务端使用随机生成的会话 ID,两个 SDK 的规则缓存刷新周期也不同。更糟的是,支付授权已经按新路径执行,关闭界面入口并不会撤销已产生的副作用。
特性开关解决的不是“把一个布尔值放到远程配置里”,而是把代码部署、功能释放、受众选择、运行时退化和长期清理放进一条可验证链路。控制台只负责表达规则;真正决定一次请求走哪条路径的是应用 SDK、评估上下文、规则快照和默认值。评估事件是否外发、缓存能否在断网时继续工作、用户能否稳定命中同一变体、谁有权修改生产规则,则决定这套工具会降低风险还是创造新的控制面依赖。
先区分四种容易混在一起的动作
部署把包含新旧实现的制品送到运行环境,释放决定哪些请求能使用新实现,放量逐步扩大目标群体,实验还要记录曝光和指标,用可解释的统计口径比较变体。一次 Kubernetes rollout 可以完成部署,却不能自动证明同一用户稳定命中新功能;一个 10% flag 可以完成稳定放量,也不自动构成有效实验。
特性开关还不能替代权限控制。前端隐藏按钮只是体验变化,服务端仍必须执行身份鉴别和授权。若客户端能够修改 context、读取公开环境标识或直接构造 API 请求,任何只依赖客户端 flag 的 entitlement 都能被绕过。许可、套餐、租户隔离和敏感操作权限必须由服务端权威数据判断,flag 只能控制实现选择或功能呈现。
| 变化对象 | 应落在哪一层 | 失败时首先检查什么 |
|---|---|---|
| 新旧应用版本与实例流量 | 发布平台、网关或编排系统 | 制品身份、实例健康、路由和数据库兼容 |
| 某个身份是否获得一个变体 | 特性开关规则与应用 SDK | targeting key、context 属性、规则版本与评估理由 |
| 普通运行参数随环境变化 | 配置中心或应用配置 | 配置来源、刷新、覆盖顺序和类型绑定 |
| 用户是否有权访问资源 | 服务端身份与授权系统 | subject、resource、action 和策略证据 |
| 变体是否改善业务指标 | 实验平台与数据链 | 曝光、转化、identity、样本和指标口径 |
从当前故障信号选择入口
| 现场信号 | 工程入口 | 首先要证明的事实 |
|---|---|---|
| 应用代码已经被某个厂商 SDK 绑住,希望保留统一评估 API 和迁移能力 | OpenFeature | typed evaluation、Provider、context 和 fallback 在切换实现后保持业务语义 |
| 团队希望自托管,重视后端 SDK 本地评估、strategy、variant、stickiness 与 flag 生命周期 | Unleash | 相同 targeting key 稳定分桶,控制面断网后使用可解释缓存或默认值 |
| 团队同时需要 remote config、identity/trait targeting、SaaS 与自托管路径 | Flagsmith | 环境密钥权限正确,身份特征不会越界外发,local/remote evaluation 行为可说明 |
| 规则希望随 Git 或 OCI 版本流转,并把配置回滚纳入代码审查 | Flipt | 配置提交、服务端加载版本和应用评估结果能够互相追溯 |
| 团队选择托管平台,需要完整 SDK、流式更新、Relay、审计和实验能力 | LaunchDarkly | SDK 类型、凭据、规则持有位置、last-known state 与事件边界符合数据政策 |
| 产品团队希望把本地特性评估与现有数据仓库中的实验指标连接 | GrowthBook | 曝光与转化使用同一 subject,feature rule 和实验分析没有身份漂移 |
| 多种产品都出现冷启动、缓存陈旧、上下文串请求或退出丢事件 | 特性评估运行时:缓存、默认值与故障模型 | 四类故障能稳定复现,并分别落到初始化、缓存、context 和事件链 |
| 开关越来越多,没人敢删,放量、实验、权限与止血用途互相混用 | 放量、实验与开关债务治理 | 每个 flag 有类型、owner、TTL、审批、回退和代码清理证据 |
选型不能只比较控制台功能。架构评审至少要画出五个位置:规则权威源、规则分发通道、评估发生位置、评估/曝光事件去向、故障时的可用状态。两个产品都支持“百分比发布”,一个可能在服务端按完整规则本地评估,另一个可能由客户端获取当前身份可见的结果;它们的延迟、隐私、断网行为和凭据风险完全不同。
一次评估怎样穿过控制面与业务请求
业务请求不应同步调用管理 API。服务端 SDK 通常先获取规则快照,再在进程内评估;客户端 SDK 可能只持有当前环境和当前身份可见的规则或结果。无论实现怎样,业务代码都要显式提供 flag key、类型匹配的默认值和最小 evaluation context,并记录足够的 reason、规则版本或快照年龄用于排障。
默认值不是“连不上就 false”的语法填充。新支付路径失联时回旧实现可能是安全的,安全校验开关失联时回旧实现却可能放过风险请求;一个 kill switch 的安全方向也可能与 release flag 相反。默认值要由业务故障分析决定,并通过冷启动无配置、运行中断网、规则陈旧和 context 缺失四类实验验证。
稳定分桶依赖稳定身份
百分比放量通常不是每次随机抽签,而是把 flag key + targeting key 经过稳定散列映射到固定区间。只要规则、salt 和 targeting key 不变,同一 subject 应持续得到同一变体。使用请求 ID、临时会话 ID、会变化的邮箱或数组顺序不稳定的复合字符串,会让用户反复换组;客户端和服务端使用不同 key,又会让一次用户旅程在两个实现之间撕裂。
匿名到登录的身份切换也要设计。登录前使用设备匿名 ID,登录后改用账户 ID,变体可能合法改变;若这个变化发生在结算流程中间,就可能制造页面与服务端状态不一致。团队应明确哪些旅程必须固定身份、何时允许重新评估、跨设备是否要求一致,以及合并匿名与登录事件时怎样避免重复曝光。
实验比普通放量多一条数据合同:在用户真正遇到变体时记录曝光,用同一 subject 记录后续转化,并保证指标窗口、排除规则和数据去重一致。应用启动时预先评估全部 flags 会制造虚假曝光;缓存业务结果后绕过 SDK,也可能让真实体验没有对应事件。实验平台的绿色图表不能替代曝光链路的正反验证。
故障时应保住哪一种状态
评估链至少存在四种不同故障:进程第一次启动就拿不到规则;运行一段时间后控制面断网;规则已经陈旧但仍可评估;context 缺少关键属性或发生串请求。四者不能统一处理成“返回 false”。
冷启动没有可信快照时,启动可以失败、进入受限模式,或使用随制品发布的 bootstrap;选择取决于错误方向的业务代价。运行中断网时,last-known-good 能保住已验证行为,但要暴露快照年龄、最后同步时间和 provider 状态,防止永久陈旧。规则解析失败时,不要用半份新规则覆盖完整旧快照;更新应当原子化,失败后保留旧版本并报警。
context 缺失时,应区分“规则明确不匹配”和“评估输入无效”,否则数据质量问题会伪装成正常关停。
可观测性至少包含评估次数、默认值命中、error reason、规则快照年龄、同步失败、变体分布和事件队列积压。不要把完整 context 写进日志或 trace baggage;高基数用户标识既会泄露隐私,也会推高日志和指标成本。排障通常只需要不可逆哈希、环境、flag key、variation、reason、规则版本和 trace ID。
从单服务试点走到团队能力
试点选择一个可回退、无数据副作用的内部功能。先在开发环境完成固定值与按身份规则,再增加稳定百分比分桶;随后故意删除 flag、填错凭据、阻断控制面网络并重启应用,确认每种失败都有不同证据。只有正向打开和关闭成功,不能证明这套工具能承受事故。
第二阶段把 flag 元数据纳入仓库或工单:名称、类型、owner、创建原因、安全方向、预计清理条件、影响服务、监控、回退动作和审批人。CI 可以扫描未知 flag、过期 flag 与类型不匹配,但不能直接凭字符串搜索自动删除业务分支。代码清理要经过“固定最终变体、等待最老实例和缓存退出、删除旧分支、删除监控和配置、归档审计”的完整链路。
第三阶段才讨论平台化:环境晋级、模板、Relay/Edge、SSO、审计导出、事件保留、成本预算和供应商退出。自托管团队要负责数据库、配置仓库、加密密钥、镜像、备份恢复和升级;SaaS 团队仍要负责凭据轮换、上下文数据最小化、事件成本、账号回收与降级方案。把运维责任从供应商名下移到内部平台团队,不会因为控制台是云服务就自动消失。
交付前必须拿到的证据
同一 targeting key 在重复请求、不同实例和必要的多语言 SDK 中稳定命中同一变体。缺失 flag、类型不匹配、无效凭据、冷启动断网和运行中断网分别产生预期 fallback、reason、日志和告警。客户端只持有可公开标识;服务端密钥、Admin token 和完整规则没有进入浏览器、移动包、日志或截图。
context 只携带评估必要字段,敏感属性按平台能力设为私有或不发送;事件保留和采样符合团队政策。关闭 UI flag 后,服务端授权仍独立生效;任何可被客户端篡改的值都不能授予资源访问权限。开关变更有 owner、审批、审计和回退动作,紧急 kill switch 也有事后复核与恢复条件。
自托管控制面的数据库、配置、加密材料和 bootstrap 能恢复;SaaS 失联时应用有经过演练的可用状态。实验曝光与转化使用同一 subject,虚假预评估、重复事件和身份切换有检测或排除办法。flag 到达最终状态后,旧代码、测试、配置、监控、文档和平台对象按顺序清理,归档记录仍可追溯。
当一次功能释放能够回答“谁在什么规则版本下得到了哪个变体、为什么得到、控制面故障时用了什么状态、变化产生了哪些技术和业务证据、怎样立即止损、什么时候删除旧分支”,特性开关才从远程布尔值升级为可治理的工程能力。
