题干与适用场景
这是面向平台、云基础设施和嵌入式系统岗位的系统设计题。设备可能长期离线、存储有限、网络昂贵,错误固件会让整批设备失联。平台必须保证只有兼容设备能安装已签名包,发布可以暂停,设备可恢复或回到上一版本。
默认一百万台设备、每日最多 100,000 台并发下载;更新包 20 MiB;设备按型号、硬件修订、地区和当前版本分组。题目不要求选定 AWS,云服务只是帮助说明状态和控制面边界。
面试官考察点
- 是否把包完整性、来源认证、设备授权和兼容性检查分开。
- 是否设计控制面与设备数据面的状态机,而非只画一个文件下载桶。
- 是否能计算带宽、并发和失败阈值,并说明暂停、重试、回滚与人工介入条件。
强回答会把“发布成功”定义为设备验证、安装、重启和健康回报,而非 CDN 下载完成。
回答前需要澄清的问题
- 设备能否双分区启动? 双分区允许先写非活动槽并在启动失败时回退;单分区需要更保守的引导程序和现场恢复路径。
- 更新是否有安全或监管区域限制? 目标筛选必须包含型号、硬件版本、地区、证书状态和当前版本,不能只用设备标签。
- 设备多久必须更新? 期限决定批次大小、维护窗口、离线设备重试和是否允许强制安装。
- 失败是设备级还是批次级? 设备失败可重试;同一固件在某型号上的失败率升高应暂停该分组,而不是继续全局扩量。
30 秒回答框架
“我把平台拆成签名包仓库、发布控制面、设备代理和遥测回报。发布前生成带型号、硬件、版本、依赖和过期时间的 manifest,离线签名并让设备在安装前验证签名、摘要和兼容条件。控制面按目标分组做 canary、固定或指数速率 rollout,保存每台设备的状态和幂等 job ID;设备下载支持分块断点续传,写入非活动分区,重启后健康检查成功才提交。失败率、下载错误、启动回退或安全告警超过阈值就暂停并保留旧版本。离线设备按维护窗口重试,所有动作进入审计和回放日志。”
分步骤深入解答
第一步:计算主要瓶颈。
若一百万台设备都下载 20 MiB,总量约 20 TiB。每日完成 100,000 台意味着平均约 2 TiB/日,约 23.7 MiB/s;峰值还要乘以并发和重试余量。对象存储和 CDN 承担包分发,控制面只发送 manifest 和短期下载授权,不能让设备轮询大型数据库。
第二步:建立不可伪造的包与 manifest。
构建流水线生成不可变包、摘要和 manifest。签名密钥放在受控签名服务,发布记录保存签名版本和审批。设备内置信任根,验证签名、包摘要、目标型号、最低 bootloader、版本防回滚计数和过期时间;下载地址本身不是信任边界。
第三步:分离控制面和数据面。
控制面创建发布、目标查询、批次、设备 job 和暂停命令;设备数据面从 CDN 分块下载并向 job 端点回报状态。每台设备以 (deviceid, jobid) 幂等更新,重复上报不推进错误状态。状态至少包括 QUEUED、DOWNLOADING、VERIFIED、INSTALLING、SUCCEEDED、FAILED、ROLLED_BACK 和 REJECTED。
第四步:设计安全安装与回滚。
设备先把包写入非活动槽,逐块校验摘要,完成后验证 manifest,再切换启动槽。引导程序记录尝试次数和启动确认;应用在健康检查、关键传感器和通信恢复后提交确认。连续失败回退旧槽,并把原因和启动计数上传。单分区设备需要恢复镜像或现场维护,不能假设同样的原子切换。
第五步:控制 rollout。
先在内部设备和小型 canary 组发布,再按型号和地区逐步扩大。速率可以固定或指数增长,但每一组都设置最大并发、维护窗口和 abort 条件。失败阈值按设备组计算,区分下载失败、签名拒绝、安装失败、启动回退和健康检查超时。
第六步:处理离线、重试与审计。
设备上线后领取尚未过期的 job;下载使用断点续传和指数退避,重试必须复用同一 job 与包版本。超过 deadline 的设备进入待处理列表,不直接标记成功。控制面保留发布审批、manifest、目标快照、状态转移、操作者和暂停原因,支持重放和合规追溯。
高质量示范回答
“我会先拆出控制面、包仓库/CDN、设备代理和遥测系统。发布流水线生成不可变包和 manifest,manifest 写明目标型号、硬件修订、最低 bootloader、版本计数和摘要,由离线或受控签名服务签名;设备用内置信任根验证,下载 URL 只负责传输。
假设一百万台设备、20 MiB 包、每天完成十万台,包总量约 20 TiB,因此 CDN 承担分发,控制面只保存发布和每台设备的 job 状态。设备分块下载到非活动槽,完成摘要验证和重启健康检查后才提交;失败就回退并报告原因。发布先走 canary,再按型号和地区逐步加速。对每组设置并发、失败率和回退率阈值,超过就暂停,不自动把坏包扩散。离线设备在维护窗口领取同一 job,重试可恢复,所有状态、审批和版本都可审计。”
常见错误
- 错误表现:只校验 HTTPS → 失败原因:传输安全不证明包来源和内容未被替换 → 修正方法:设备验证 manifest 签名和包摘要。
- 错误表现:下载完成就标记成功 → 失败原因:安装、启动和健康检查可能失败 → 修正方法:把成功定义为启动确认后的终态。
- 错误表现:全量同时发布 → 失败原因:一个兼容性错误会影响整个设备群 → 修正方法:canary、分组、速率和 abort 条件。
- 错误表现:每次重试创建新任务 → 失败原因:状态重复、审计断裂且无法恢复 → 修正方法:复用
(deviceid, jobid)幂等状态。 - 错误表现:允许任意版本回滚 → 失败原因:攻击者可能诱导设备安装旧漏洞版本 → 修正方法:签名版本计数、防回滚策略和受控回退清单。
追问及应对
追问一:发布到 2% 时某型号启动回退率达到 4%,怎么办?
立即暂停该型号和同一包版本的后续 rollout,保留已成功设备的监控。按硬件修订、bootloader、地区和包构建切片,确认是否为单一兼容组合;必要时发布已验证的旧版本或恢复命令。不要因为全局平均失败率低就继续扩量。
追问二:设备下载到 80% 后断电,如何保证下次不会重头开始?
分块写入非活动槽,并保存包版本、块摘要、已确认偏移和整体 manifest 摘要。重启后设备验证本地块和 manifest,再从最后连续可信块请求范围下载。若包版本或签名变化,丢弃旧临时槽,避免把两个版本拼在一起。
追问三:如何防止攻击者把合法旧包重新推送?
manifest 包含单调版本计数或安全版本号,设备持久化已接受的最高值;引导程序拒绝低于策略的包。紧急回退必须由受控签名、明确设备组和时限授权完成,并把例外写入审计,不能让普通下载接口绕过防回滚。