开场:早期产品也需要可控发布
很多 SaaS 小团队觉得功能开关是大公司才需要的。
早期只有几个客户,开发完直接上线就好。问题是,SaaS 的风险不是从客户数量很多才开始,而是从客户把你放进真实流程那一刻开始。
一个未验证的新功能,可能影响老客户的稳定流程;一个只适合试点客户的入口,可能让所有客户误用;一个尚未收费的高级能力,可能提前暴露给低价套餐。
功能开关的目的不是制造复杂架构,而是让小团队能更安全地发布、试点、收费和回滚。
功能开关解决哪些早期问题
| 问题 | 没有开关时 | 有开关时 |
|---|---|---|
| 新功能试点 | 全量上线或单独分支 | 只给指定客户 |
| Bug 回滚 | 重新部署 | 关闭入口或能力 |
| 套餐差异 | 代码里到处判断 | 集中控制权益 |
| 客户定制 | 分叉版本 | 用配置表达差异 |
| 内部测试 | 用测试环境猜 | 生产少量账号验证 |
早期功能开关要简单,但不能没有。
从四种开关开始
不需要一开始引入复杂平台。可以先设计四类。
| 开关类型 | 用途 | 示例 |
|---|---|---|
| 客户开关 | 指定租户可用 | 只给 A 公司打开批量导入 |
| 角色开关 | 指定角色可用 | 只有管理员能看到审计日志 |
| 套餐开关 | 权益控制 | Pro 才能使用自动报表 |
| 实验开关 | 小范围验证 | 10 个账号看到新版引导 |
这四类基本覆盖早期 80% 的发布场景。
不要把开关写散
坏做法是在页面和接口里到处写:
if customer_id == "abc" { showNewFeature() }
这样很快会失控。三个月后没人知道哪个客户开了什么、为什么开、什么时候关。
更好的做法是建立一张最小配置表。
| 字段 | 含义 |
|---|---|
| feature_key | 功能标识 |
| scope_type | tenant、role、plan、experiment |
| scope_value | 具体客户、角色或套餐 |
| enabled | 是否开启 |
| expires_at | 过期时间 |
| owner | 负责人 |
| reason | 为什么开启 |
即使暂时用配置文件,也要保留这些信息。
每个开关都要有关闭路径
功能开关不是只负责打开,还要能安全关闭。
上线前问清:
- 关闭后用户看到什么。
- 已创建的数据如何展示。
- 关闭是否影响正在运行的任务。
- 是否需要通知客户。
- 谁有权限关闭。
例如自动报表功能关闭后,历史报表仍可查看,但不再生成新报表。这比直接隐藏整个页面更安全。
试点客户开关要设过期时间
早期常见问题是给客户开了试点功能,然后忘记清理。
结果是:
- 客户长期免费使用高级能力。
- 产品行为和套餐说明不一致。
- 销售不知道客户到底开了什么。
- 后续改动不敢动。
每个试点开关都应该有过期时间。到期时做三选一:转正式套餐、延长试点、关闭。
功能开关不是权限系统
功能开关和权限有关,但不能完全替代权限。
| 系统 | 解决问题 |
|---|---|
| 权限 | 谁能访问什么资源 |
| 套餐 | 客户买了哪些能力 |
| 功能开关 | 某能力在某范围是否可见或可用 |
不要用功能开关来绕过数据权限。比如“普通成员不能看工资数据”应该是权限系统处理,不是开关处理。
开关命名要稳定
不要用临时名字。
| 差命名 | 好命名 |
|---|---|
| new_page | billing_invoice_export |
| test_v2 | onboarding_checklist_v2 |
| customer_a_feature | bulk_import_orders |
| ai_try | support_reply_suggestion |
功能标识会进入日志、客服排查、销售说明和套餐配置,命名越清楚,后面越少误会。
每周清理一次开关
功能开关会变成另一种技术债。
每周看一次:
- 哪些开关已经全量打开,可以删除判断。
- 哪些试点开关过期。
- 哪些客户开关没有负责人。
- 哪些实验没有结论。
- 哪些套餐开关和官网说明不一致。
早期可以把开关清单放在 Notion 或表格里,但必须有人负责。
落地建议
先为下一个新功能设计客户级开关和关闭路径。不要等系统复杂后再补。
SaaS 从 0 开始,发布速度很重要,但可控性同样重要。功能开关让你既能快,又能在客户真实业务里保持基本稳定。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。