十月补记:本文于 2026 年 10 月 25 日整理并首次发布,页面日期用于归档对应时期的实践;后续修整一并写入。产品开放范围以文中链接的公开说明为准。
有时一次软件发布已经完成大半:代码检查过,软件包也做好了,最后却在下载或读取文件时遇到一次网络失败。
如果处理方式只有“整套重新跑”,就要再次等前面已经成功的步骤。尤其是 Mac 软件还涉及签名和较大的安装文件,一次暂时的读取问题,会被放大成很长的等待。
整理陪练的交付准备时,我更想把失败放回它实际发生的位置:哪些结果已经可靠地留下,哪一步可以安全地再做一次?
重试之前,先分清这一步在做什么#
读取一份固定文件,和提交一次会改变状态的操作,风险不同。前者通常可以设计为重新读取;后者要先确认上一次究竟有没有生效。
即便是读取,也不能对所有错误统一重试。临时连接中断、上游暂时不可用,可能值得再试;来源不对、没有权限、内容校验失败,反复请求通常不会变好。
| 看到的情况 | 我会先怎样处理 |
|---|---|
| 暂时网络中断 | 看是否允许有限次数的读取重试 |
| 权限或来源被拒绝 | 停下来核对,不把拒绝当作网络抖动 |
| 文件不完整 | 丢弃本次半成品,再按规则重新取得 |
| 已触发安装等写操作 | 查询原操作状态,避免重复执行 |
小步骤能重试,整个任务也要有截止点#
重试可以解决一次偶发失败,也可能让失败永远不结束。我会同时保留单次请求的超时、允许的重试次数和外层任务的总期限。
还有一个容易遗漏的地方:重试不能把整个截止时间重新归零。否则每一小步都看起来“还没超时”,用户却已经等了很久。
错误也要回到能行动的描述上。比如“读取阶段连接中断,可以稍后重试”和“内容校验未通过,未进入发布”,比统一写“未知错误”更有帮助。公开信息只给出阶段和类别,不显示内部主机或鉴权信息。
重新拿到文件以后,仍要重新核对#
下载完成只说明这次收到了内容,还要检查长度、摘要和来源。上一次残留的半包不能被当成完整新包,重试也不应跳过已有验证。
我希望文件只有在验证完成后,才进入下一环节;验证失败的临时内容单独处理,已经验证的原始结果仍然能找回。这样一个小步骤失败,不会顺便破坏前面完成的工作。
可以用固定的合成文件测试:第一次读取中断,第二次正常;连续失败直到总期限;权限拒绝时不继续;收到不匹配内容时不发布。每一种都应该留下不同结果。
这项改动,应该怎样看收益#
最直接的收益是减少不必要的全量重跑。要量化,还得记录失败发生在哪个阶段、局部恢复花多久,以及有多少次真的因此避免了重新打包。
一条恢复测试通过,说明这种失败路径有依据;它不代表生产网络永远稳定,也不代表尚未开放的在线更新已经正式启用。
我现在更愿意把发布流程设计成几个有明确结果的小步骤。成功的部分能留下,失败的部分能定位,重试才不需要把整件事推倒重来。