题干与适用场景
这是一道系统设计题,核心不是争论 URL 版本还是 Header 版本,而是设计一套 API 生命周期控制平面。它要从契约变更进入影响分析,找到真实消费者,验证新旧版本行为,分阶段通知和迁移,最后用证据决定是否停用。Microsoft 建议尽量保持向后兼容,Google Cloud 也强调先尝试兼容式演进;题目要求你把原则落成跨团队可运行的系统。
面试官考察点
- 能否区分格式兼容、实体语义变化和真正的破坏性变更。
- 能否把 API 契约、消费者清单、运行时流量和迁移任务连接起来。
- 能否设计兼容性测试、灰度、告警、通知和回滚,而非只给版本号。
- 能否解释多版本支持的运维成本、数据转换风险和组织协作边界。
回答前需要澄清的问题
先确认 API 是内部、合作伙伴还是公开 API,消费者是否能被完整识别,调用量、延迟和可用性目标是什么。再明确要删除的字段是否可选、是否改变语义、是否涉及写入和持久化数据;确认是否已有 OpenAPI 或其他契约源、客户端 SDK、通知渠道、支持期限、合规要求和回滚窗口。若题目没有给规模,应先声明估算假设。
30 秒回答框架
我会按“契约注册、影响发现、兼容验证、迁移协调、停用证明”五段设计。所有 API 契约进入注册中心,变更先由规则引擎判断兼容性,再结合静态依赖和运行时调用识别消费者。新旧版本并行提供,消费者收到带截止时间和迁移指南的通知;灰度期间按版本记录成功率、错误和残余流量。只有旧版本零关键流量、迁移任务完成、回滚方案演练通过并经过审批,才执行停用。
分步骤深入解答
1. 建立契约注册中心和变更规则
注册中心保存 API、版本、所有者、字段语义、认证范围、支持状态、弃用时间和迁移文档。变更请求关联契约 diff,规则引擎识别删除字段、收窄枚举、改变必填性、改变错误语义和实体关系等风险。新增可忽略字段通常是兼容式变更,但不能假定所有客户端都正确忽略未知字段;规则应允许团队提交有证据的例外。
2. 发现消费者并构建影响图
消费者目录合并代码仓库依赖、网关日志、服务网格遥测、SDK 注册和人工声明,形成 API—版本—消费者的关系图。静态发现可能漏掉动态拼接请求,运行时发现可能漏掉低频任务,因此要标记证据来源、最后观测时间和置信度。对外部客户端只保留必要的租户和应用标识,避免把日志当成无限期个人数据。
3. 兼容性验证与安全护栏
每次变更运行契约测试、消费者回放和样本流量比较;读路径检查新旧响应语义,写路径验证旧客户端请求不会丢数据或产生错误副作用。破坏性变更先在影子或小租户灰度,版本路由和功能开关必须可回退。失败时保留旧版本,不能用“测试通过”覆盖未纳入测试的消费者。
4. 通知、迁移和多版本运行
通知服务按消费者、严重性和支持合同发送迁移指南、截止时间、示例请求和联系人;外部客户要有可查询的状态页或控制台。迁移任务记录负责人、阻塞原因、验证结果和最后一次成功调用。多版本会增加测试、部署和监控成本,应该设定版本上限、弃用阶段和升级路径,而不是无限期保留旧版本。
5. 停用决策、观测与恢复
停用前检查关键消费者已升级、残余调用低于门槛、错误率无回归、数据转换可逆、支持团队已准备。停用采用分区和时间窗口,先拒绝新接入,再对旧调用返回明确的弃用错误和迁移链接,最后关闭路由。指标包括兼容性失败、旧版本请求量、迁移完成率、通知送达率、回滚次数和按消费者分层的错误率。Kubernetes 的弃用政策展示了稳定级别、最短支持期、转换和回滚约束;系统应把这些约束配置化,而不是照抄成所有公司的期限。
高质量示范回答
我先确认消费者类型、契约源、要删除字段的读写语义、外部通知义务和回滚窗口。架构上建立契约注册中心,变更进入规则引擎,识别破坏性差异并关联影响图;影响图由代码依赖、网关日志和服务网格遥测共同构成,并标注证据新鲜度。兼容性测试、消费者回放和灰度流量验证新旧行为,通知服务给每个消费者发送迁移指南和截止时间。新旧版本并行运行,迁移任务记录验证证据,只有关键消费者完成、残余流量和错误率达标、回滚演练通过并获审批,才分阶段停用。所有变更、通知、观测和回滚写入审计日志,防止未知客户端被一次性切断。
常见错误
- 只讨论 URL、Header 或语义化版本号,没有消费者发现和停用证据。
- 只依赖静态代码搜索或单一访问日志,忽略动态调用和低频任务。
- 把删除可选字段当成必然安全,未验证旧客户端的真实解析行为。
- 同时上线新版本并立即关闭旧版本,没有灰度、回滚和迁移窗口。
- 无限期支持所有版本,未计算多版本测试、监控和数据转换成本。
- 只发一封邮件,没有截止时间、责任人、阻塞升级和分层指标。
追问及应对
找不到某个外部客户端,怎么判断可以停用?
把“不确定”当作风险状态,延长观测窗口并提高日志粒度,联系合同联系人或提供自助迁移诊断。不能把零日志等同于零使用,停用前应设置可恢复的拒绝策略和紧急回退通道。
新增响应字段真的总是兼容吗?
不总是。契约规则可以把新增字段标为通常兼容,但仍要用真实消费者回放、SDK 版本矩阵和错误样本验证;对严格 schema 校验的客户端,需要单独迁移或版本隔离。
旧客户端写入的数据如何安全迁移?
先定义字段语义映射和不丢失条件,使用双读、双写或离线转换并记录版本。转换必须可验证、可回滚,不能在读取时悄悄改变业务含义。
客户在截止日期前无法升级怎么办?
按支持合同和风险等级提供有限的兼容窗口、适配代理或人工迁移,但要记录成本、负责人和新的退出日期。例外应减少未知流量,而不是把旧版本永久变成默认路径。
如何防止弃用控制平面本身成为单点故障?
数据面路由不应依赖实时控制平面写入;缓存已批准的版本策略,控制平面故障时保持最后安全配置。注册、通知和指标服务可异步恢复,停用动作必须有双人审批和显式回滚。