共享要比较省下的重复工作与新增维护、迁移和故障影响;6小时降到2小时只是某个情景的试验目标。
一、一次升级,全线宕机
以下情境为教学假设,人物、引语和数字不代表经核实的真实案例。
一位开发者用一套共享代码做了三个产品。某天他升级了共用的认证模块,本地测试通过,直接部署。两个小时后,三个产品的登录同时失效——升级改动了一个会话字段,而只有一个产品跟着改了数据库。
他花了整个周末回滚、修数据、给用户发解释邮件。
这个故事的教训不是「不要共享」,而是:共享的东西必须有版本、有边界、有回滚路径。
判断反例:五个产品各月收500美元、现金成本各16美元、维护各6小时,按50美元/小时计,其经济贡献仍有920美元,不需要先压到2小时才能成立。若共享减少重复维护20小时,却增加8小时共享层工作,净节省只有12小时,还须评估关联故障,不能把20小时全部当收益。
二、可以共享的六层
共享的正确对象是与业务无关的基础能力。判断标准是:如果把它换掉,产品对用户的价值不变。
| 层 | 共享什么 | 不共享什么 | 收益 |
|---|---|---|---|
| 认证 | 登录、会话、密码重置、OAuth | 权限模型、角色定义 | 可能减少重复开发;节约工时需实测 |
| 计费 | 支付通道、订阅状态、发票、退款流程 | 价格表、套餐定义、试用规则 | 省掉重复对接与对账 |
| 邮件 | 事务邮件发送、模板渲染、退订管理 | 品牌文案、发送节奏 | 统一送达率与合规 |
| 日志与监控 | 错误上报、可用性探测、告警通道 | 业务指标定义 | 一套告警就能覆盖全部产品 |
| 备份 | 备份任务、校验、保留策略 | 数据模型与恢复流程 | 避免某个产品没人管 |
| 法务页 | 隐私政策、服务条款、Cookie 说明的骨架 | 具体业务描述与数据处理范围 | 减少重复起草与遗漏 |
2.1 认证:共享会话,不共享权限
认证可以共享的部分是「你是谁」,不应该共享的部分是「你能做什么」。
- 共享:身份、会话、密码策略、双因素、OAuth 回调。
- 独立:角色、权限、组织/团队结构、邀请流程。
权限库可以复用,但产品/租户命名空间、角色定义、授权数据和测试边界必须清楚;共享实现不等于共享所有用户权限。
2.2 计费:共享通道,不共享套餐
支付通道对接是重复劳动最多的一块:Webhook 校验、订阅状态同步、退款、发票、税务。这些可以共享。
套餐、价格、试用期、优惠券规则必须独立。不同产品的价值主张不同,定价逻辑强行统一会同时伤害两边。
2.3 邮件:共享发送,不共享语气
事务邮件的发送链路、重试、退订、退信处理可以共享;模板的语气、品牌、发送时机应该独立。
一个面向企业的产品和一个面向个人的产品,邮件语气完全不同。共享模板会显得两边都不专业。
三、不该共享的三层
| 层 | 为什么不能共享 | 强行共享的后果 |
|---|---|---|
| 数据模型 | 每个产品的核心实体不同 | 表结构互相妥协,查询变慢,迁移互相阻塞 |
| 领域逻辑 | 业务规则是产品的差异所在 | 改 A 的规则会悄悄改变 B 的行为 |
| 品牌语言 | 用户群与定位不同 | 定位模糊,两个产品都显得不专注 |
3.1 共享数据库是最常见的事故源
共享数据库看起来省事,实际上把三个产品绑成了一个:任何一次 schema 迁移都要同时考虑三个产品的兼容性,任何一次数据事故都会同时影响三个产品。
如果确实要共享,共享的是数据库实例,不是数据库 schema。每个产品明确数据所有权、迁移和备份边界;独立 schema 还需要独立数据库角色、访问控制与恢复测试,不能防实例故障或管理员越权。
四、三种复用形态
| 形态 | 做法 | 优点 | 缺点 | 适用阶段 |
|---|---|---|---|---|
| 复制粘贴 | 每个产品各有一份代码 | 简单、隔离彻底 | 修 bug 要改 N 次 | 2 个产品、早期 |
| 私有包 | 抽成内部库,按版本引用 | 一次修复,多处升级 | 需要版本管理与发布流程 | 3 个以上产品 |
| 多租户平台 | 一套代码,配置区分产品 | 边际成本最低 | 架构复杂,隔离风险高 | 产品高度同质 |
不要过早进入第三种。 多租户平台适合「同一类产品、不同配置」的场景;如果产品之间差异明显,强行平台化会让每个产品都变得平庸。
4.1 从复制粘贴到私有包的时机
出现下面任意两个信号,就该考虑抽成私有包:
- 同一个 bug 在三个产品里各修了一次。
- 同一个安全补丁需要手动应用到三处。
- 你开始记不清哪个产品用的是哪个版本。
五、升级不炸全线的版本策略
共享底座最大的风险是「一次改动,全线受影响」。用下面四条把风险关进笼子:
- 语义化版本。 破坏性改动升主版本,新增功能升次版本,修复升补丁版本。
- 逐产品升级。 不要一次把所有产品升到最新版;先升一个低风险产品,观察一周。
- 灰度与开关。 影响行为的新逻辑放在开关后面,默认关闭。
- 可回滚。 每次升级前确认上一个版本还能部署,数据库迁移有回退方案。
5.1 一张升级记录表
| 字段 | 说明 |
|---|---|
| 底座版本 | 例如 auth@2.3.1 |
| 涉及产品 | 哪些产品已升级 |
| 升级时间 | 日期 |
| 变更内容 | 一句话 |
| 验证方式 | 登录、支付、邮件各测一遍 |
| 回滚方案 | 回退到哪个版本,数据是否可逆 |
这张表不需要工具,一个 Markdown 文件就够。它的价值在于出事时你知道上一次好的状态是什么。
六、共享底座的成本回收
共享不是免费的吗?不是。抽底座本身要花时间,维护底座也要花时间。
| 投入 | 一次性/持续 | 估算 |
|---|---|---|
| 抽出认证模块 | 一次性 | 3–5 天 |
| 抽出计费模块 | 一次性 | 5–10 天 |
| 建立版本与发布流程 | 一次性 | 2–3 天 |
| 每次底座升级的验证 | 持续 | 每个产品 0.5–1 小时 |
产品数不是回本门槛。回收月数 = 一次性抽象工时 ÷(每月避免的重复工时 − 新增底座维护和升级工时),仅当分母大于零时有有限回收期。
七、常见错误
| 错误 | 后果 | 更好的做法 |
|---|---|---|
| 共享数据库 schema | 迁移互相阻塞 | 共享实例,独立 schema |
| 共享权限模型 | 改一个产品影响全部 | 只共享身份,不共享权限 |
| 共享定价逻辑 | 定价互相牵制 | 共享通道,独立套餐 |
| 没有版本号 | 不知道哪个产品跑的是哪版 | 语义化版本 + 升级记录 |
| 一次升级全部产品 | 一次事故全线宕机 | 逐产品升级,先低风险 |
| 未测重复成本就抽平台 | 过度设计或长期复制漏洞 | 估算回收期并验证安全隔离 |
八、行动清单
- 列出当前所有产品共用的东西。
- 按「可以共享 / 不该共享」两张表逐项归类。
- 检查是否共享了数据库 schema 或权限模型,如果是,制定拆分计划。
- 给共享底座加版本号,并建一张升级记录表。
- 确认每个产品都能独立回滚。
- 评估当前产品数量是否值得抽私有包。
- 把「共享边界」写成一页文档,新加产品时先对照。
使用边界与实操验收
复用与运行时共享是不同决定:版本化库可复用代码而独立部署;共享服务要额外承担可用性和隔离设计。SemVer 只约定公共 API,不能自动保证数据库兼容。
回收样例:抽离计费库花 24 小时,每月节省 8 小时重复修复,但底座维护与逐产品验证增加 2 小时,回收约 24÷6=4 个月;若只节省 1 小时则分母为负,不回本。隔离验收再测试 A token 无法读 B 数据、A schema 角色无法访问 B、A 升级失败时 B 仍可部署旧库。
关键参考与核验范围
以下链接支持对应的机制或规则;本文的案例、成本和经营评分是说明方法的假设,不能当作平台统计或收益承诺。核验日期:2026-10-22。
系列导航
- 上一篇:组合的经济学:注意力、现金与边际成本
- 下一篇:一个人的时间分配:怎么同时维护 N 个产品
- 回到目录:一个人的产品线:第二个产品与组合运营
- 相关阅读:SaaS 技术债政策 、独立开发者的全栈模板
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。