# R2.4.7 任务报告

## 结论

错误 #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 的完整时间线是：

1. 内部渠道监控发起请求；
2. 约 30 秒仍无响应头，监控 HTTP client 取消请求并记录 timeout；
3. 网关上游请求忽略该取消，继续等待账号 31；
4. 约 54.3 秒账号 31 返回 502；
5. handler 触发 failover，但原始监控 request context 已取消；
6. 选号立即 `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 整体故障证据。

## 调优候选

1. 内部监控：把响应头 timeout、总请求 timeout 和 cadence 从硬编码提升为原生可配置事实，并在 CLI 展示来源；timeout 必须与网关每跳 deadline/failover reserve 联合设计，不能只单独放大。
2. 网关源码：统一上游与 failover 生命周期，记录 client deadline、hop deadline、remaining budget 和 cancel source。客户端断开后若无需继续工作，应取消首轮上游；若要内部完成 failover，则选号与下一跳必须使用有界内部 context，同时停止无意义的下游写回。
3. 配置缓解：精确短语 `error code: 502` 可进入通用非 auth 502 临时不可调度模板，减少后续请求再次命中，但不能挽救首次请求。
4. 不建议仅降低全池并发；窗口无排队，故障发生在单账号长等待。

本任务只读，未修改 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。
