4.4 KiB
R2.2.22 任务报告
结论
错误 #17490(request ID 4eb9a84b-7346-47a8-bb66-fb7b44317279)已确认由 Sub2API 内部渠道监控使用的 monitor API Key(ID 19)发起。账号 https://sub2.pokexiao.com plus 0.03(ID 31)长等待后返回 502;内部监控客户端已因响应头超时取消请求,Sub2API 却继续等待被去取消的上游请求。上游错误返回后虽然进入 failover,下一轮选号使用的原始 request context 已取消,无法开始第二跳,最终记录 502。
原生 trace
- 请求:
/v1/responses,gpt-5.6-sol,同步。 - 调用方:用户 1、API Key
monitor(ID 19)。 - 单跳总耗时约 54,339 ms。
- 上游状态:502,原始 detail:
error code: 502。 - Sub2API 记录
openai.upstream_failover_switching,switch 1/10。 - 同一毫秒选号失败:
context canceled,排除账号数 1。 - 最终 HTTP 502,
reason=failover-attempted-no-candidate。
近 30 分钟另一条客户错误 #17491(request ID 426551fe-cdd4-4563-a3d0-89b97aa5ffa3)完全同型,但来自不同用户/IP,不是内部 monitor:同一账号和原始 502 detail,流式,单跳约 36,157 ms,failover 后立即 context canceled。因此内部监控 timeout 能解释 #17490,但不能解释所有账号 31 的客户穿透。
内部监控 timeout 与源码链
Sub2API v0.1.155 官方源码中,渠道监控 timeout 是 MVP 硬编码值:
monitorResponseHeaderTimeout = 30s:等待响应头;monitorRequestTimeout = 45s:单次模型请求总超时;- runner 外层使用请求超时、PING 超时和缓冲构造总 context。
网关上游转发则调用 detachUpstreamContext(ctx),其实现为 context.WithoutCancel(ctx);failover 选号继续使用 c.Request.Context()。因此 #17490 的完整时间线是:
- 内部渠道监控发起请求;
- 约 30 秒仍无响应头,监控 HTTP client 取消请求并记录 timeout;
- 网关上游请求忽略该取消,继续等待账号 31;
- 约 54.3 秒账号 31 返回 502;
- handler 触发 failover,但原始监控 request context 已取消;
- 选号立即
context canceled,没有第二跳。
内部监控的 30 秒响应头超时确实等不到本次切号,但根因不仅是 timeout 数值短,还包括“首轮上游去取消、后续选号绑定已取消 context”的生命周期不一致。
账号与策略
账号 31 调查窗口内 163 次尝试、149 次成功、14 次失败,失败率 8.59%,质量 D/69;14 次 failover 信号中 2 次客户穿透。现有模板未命中该账号的 502,临时不可调度计数为 0。
原因是规则匹配原始上游响应体。模板已有 upstream service temporarily unavailable 等关键词,但原始 body 只有 error code: 502;UI 包装消息不是规则匹配输入。
基础设施
账号 31 绑定 proxy 3:platform-infra-sub2api-pk01-local-egress-proxy,HTTP 127.0.0.1:10809;owner host-proxy-hysteria.service active/running、0 重启。Sub2API app 0 restart、无 OOM,主机接口无 RX/TX error/drop。同一 proxy 的其他账号仍有成功请求。查询时快照不能排除历史抖动,但没有本地 proxy 整体故障证据。
调优候选
- 内部监控:把响应头 timeout、总请求 timeout 和 cadence 从硬编码提升为原生可配置事实,并在 CLI 展示来源;timeout 必须与网关每跳 deadline/failover reserve 联合设计,不能只单独放大。
- 网关源码:统一上游与 failover 生命周期,记录 client deadline、hop deadline、remaining budget 和 cancel source。客户端断开后若无需继续工作,应取消首轮上游;若要内部完成 failover,则选号与下一跳必须使用有界内部 context,同时停止无意义的下游写回。
- 配置缓解:精确短语
error code: 502可进入通用非 auth 502 临时不可调度模板,减少后续请求再次命中,但不能挽救首次请求。 - 不建议仅降低全池并发;窗口无排队,故障发生在单账号长等待。
本任务只读,未修改 runtime、YAML、账号、proxy、调度或 Sub2API 源码。
原生记录闭环
channel 3 记录 15589:checkedAt 2026-07-14T08:52:45Z,latency 30,011 ms,错误为 http2: timeout awaiting response headers;对应 #17490 从约 08:52:45Z 开始、网关在 08:53:39Z 结束,证明内部监控在 30 秒先取消,而去取消的首轮上游继续约 24 秒后才返回并尝试 failover。