算法服务故障复盘应留下什么
算法服务故障复盘应从可验证的事实开始:什么时候发现异常,哪些用户路径受影响,哪些指标和日志支持判断,采取了什么动作,以及恢复如何确认。不要用未经证实的规模、时长或单一“根因故事”替代时间线。请求超时、CPU 上升和 GPU 空闲可能同时出现,但还需要 trace、线程栈、输入特征和依赖状态来区分真正原因。
输入处理是值得单独检查的一层。图片的文件大小不能代表解码后的像素和内存,文本字符数也不等于 tokenizer 后的长度。服务应在解码和模型执行之前,根据业务允许的格式、尺寸、页数、token 数与工作量做限制;限制值来自容量测试和产品需求,不宜写成所有服务通用的常数。
将防护拆成可验证的层次
入口层检查认证、内容类型、文件大小与请求速率;解析层检查图片尺寸、压缩炸弹风险和文本长度;执行层使用队列、超时、取消与资源隔离;恢复层记录失败类别、保护依赖并给用户明确反馈。进程隔离可以限制某些原生库问题,但强制终止会丢失内存状态与未完成工作,应与幂等、清理和容量策略配合,而不是作为默认修复手段。
def validate_request(image_info, token_count): if image_info.pixels > MAX_PIXELS: raise ValueError("图片尺寸超过服务支持范围") if token_count > MAX_INPUT_TOKENS: raise ValueError("文本输入超过服务支持范围") async def run_with_timeout(job): return await asyncio.wait_for(job, timeout=REQUEST_TIMEOUT)超时只会停止调用方等待;下游操作是否真正取消,要由具体客户端和运行时确认。取消后应记录结果、释放队列名额和临时资源,并避免把同一请求无限重试。对于可能修改状态的任务,还需使用幂等键与补偿流程,不能简单地再提交一遍。
复盘行动必须能验收
复盘将“观察到的现象”“确认原因”“仍待验证的假设”分开。行动项要有负责人和验收条件,例如:为图片解析添加边界测试;为模型 worker 增加请求取消传播;为输入大小建立仪表盘;为原生扩展的崩溃增加隔离实验。修改后在受控环境重放脱敏样本,观察新限制是否拦住异常输入而没有误伤正常请求。
同时保留事件的查询链接、版本、配置、证据摘要和恢复步骤。下一次故障发生时,团队可以从相同的边界开始排查,而不是只记住一句“以前有过毒丸请求”。复盘真正留下的是可执行的检测、保护和恢复路径。
还应检查告警和观察本身是否可靠。若关键指标采样缺失、日志缓冲溢出或通知没有送达,复盘需要将这些可观测性缺口作为单独问题处理。恢复后用同样的请求路径和时间窗口验证服务、依赖和队列是否全部收敛,而不是只确认进程重新启动。
对于高风险变更,安排一次小范围演练:模拟超大输入、依赖超时或取消请求,确认入口拒绝、worker 清理和用户反馈符合预期。演练结果连同失败场景写入测试集,后续版本修改时自动回归。这样保护措施不会只停留在事故发生后的临时补丁。