刷题服务压测失败先核对假设
刷题服务压测失败先核对假设
压测失败本身不说明系统“扛不住”,它只说明某个假设没有成立。带工具调用的 AI 刷题服务尤其容易把几种问题混在一起:模型响应变慢、代码执行超时、重试叠加,或者请求排进了没有上限的队列。只看某一个请求的 Trace,往往会把局部现象当成全局原因。
先把一次调用的边界定下来。请求应有唯一 ID、总超时、取消信号和工具调用轮次上限。模型提出的工具参数也不能直接执行,必须校验类型、大小和允许的操作。工具失败时返回可识别的错误类别,例如参数错误、执行超时或下游不可用;不要因为拿到错误就让模型无限次重试。
if attempt >= maxAttempts { return ErrRetryExhausted }
select { case <-ctx.Done(): return ctx.Err(); default: }
一个常见反例是:工具接口短暂变慢,调用方、模型编排层和 HTTP 客户端都各自重试。单次失败很快变成多次调用,队列继续堆积,最后连原本正常的请求也超时。此时提高并发或延长超时只会把拥塞拖得更久。应先限制总尝试次数,并让所有下游调用继承同一个 context。
压测前写清负载条件:并发如何产生、题目和代码输入的范围、模型和工具版本、容器资源限制是什么。执行时同时看排队时间、工具耗时、重试次数、超时率和拒绝率。若排队时间先上升,通常应检查队列容量和消费者;若工具耗时拉长,再检查沙箱或依赖服务。
验证不必追求一个漂亮的吞吐数字。可以构造工具超时、无效参数和客户端取消三类输入,确认请求会在预算内结束,队列不会无限增长,失败会被正确分类。压测的价值,是让异常输入停止扩散,而不是让每个请求都继续重试。
把压测场景拆开跑
不要把稳定流量、突发流量和故障注入混在一轮压测里。先用固定并发跑一段时间,确认基线的排队时间和工具调用次数;再提高到预期峰值,观察拒绝策略何时开始生效。最后单独让一个工具实例变慢,或让一部分请求返回不可重试错误。这样才能看出保护逻辑是否真的阻断了放大链路,而不是被其他噪声掩盖。
模型服务和代码沙箱的容量也应分开记录。前者常受请求长度、输出长度和供应商限流影响,后者更多受编译、运行时长和容器回收影响。两者混成一个并发数,很容易让团队误以为“服务容量不够”,却不知道该扩哪一层。压测报告里写明每个阶段使用的题目比例、代码长度和工具类型,比给出一个笼统 QPS 更有用。
失败后的观察点
失败出现后先保留少量有代表性的请求链路:入口接收时间、排队时间、每次工具尝试和最终响应原因。不要为了排查把完整题目和用户代码塞进日志。若需要复现,使用脱敏后的固定样本和当时的配置快照即可。压测结束后还要观察一段恢复期:队列是否排空、连接池是否回落、被取消的任务有没有继续占用资源。能平稳恢复,才说明限流和取消并非只在图表上好看。
压测结论还要标出没有覆盖的条件,例如第三方模型限流、超大代码编译或跨区域网络抖动。它们不是可以忽略的脚注,而是下次补样本的依据。这样服务发生变化后,团队知道该重跑哪一组,而不会把旧报告当成永久容量承诺。
更多推荐

所有评论(0)