12 KiB
12 KiB
账号池排障
客户可见错误与配置调优
- 先用
runtime errors --since <window>获取全账号同窗口证据:- 以 Sub2API 原生 dashboard overview 的请求分母、客户错误率和上游错误率为主。
- 以 account availability、concurrency 和 upstream errors 解释账号可用性、排队、状态码与根因。
- 内部 monitor 使用真实 API key 和正式入口产生的错误必须纳入正式错误率、账号归因、trace 和调优判断;只单独标注调用方类别,不得因其不是外部客户而剔除或降级为测试噪声。
- 原生 system-log 索引缺少策略事件时,才使用 target runtime 日志补临时不可调度、failover、
account_select_failed和forward_failed,并保留 fallback 披露。
- 从客户可见错误中选有限 request id 运行
trace,按请求链区分:- 上游失败后成功切号。
- 切号后候选耗尽。
- 首次选号即无候选。
- HTTP 200 已提交流式响应后出现
forward_failed的 degraded 请求。
- 规则证据必须同时包含真实 HTTP 状态码与响应体关键词:
- 只有状态码、通用包装文案或推断出的原因不能扩展关键词。
- 只有
account_temp_unschedulable才证明规则命中;不能用相同状态码再次出现来推断规则失效。 - 优先使用精确短语,避免把
context window、认证失败、模型不支持等不可互换错误混入通用不可用规则。
- 无候选或模型路由错误使用现有正式只读入口:
runtime get --account <selector>读取账号配置和调度状态;runtime errors --account <selector> --full读取原生 Ops 已观测模型证据。- 配置声明与已观测模型必须分开报告,不能把历史请求模型误当作实时上游能力。
- 没有账号真实支持目标模型时,保持池不声明该模型并快速失败,不映射到名称相近的其他模型。
- 没有原生实时能力接口时只能标记证据不足,不能据此补映射。
- 调优按所有权下发:
- 非 auth 上游错误优先抽象为通用临时不可调度模板:
- 规则同时使用真实状态码和已证实的稳定响应短语;
- 先从当前 Sub2API 源码确认规则命中会在响应提交前触发当前请求 failover;
- 禁止在模板、CLI 或源码中硬编码账号名称、账号 ID、provider URL 或分组特例;
- 禁止用通用 400、通用
invalid request或宽泛关键词覆盖真实客户参数错误;
- auth、token revoked、余额不足、分组删除和凭据失效使用专门的认证与账号状态路径,不混入通用非 auth 模板;
- 通用模板先修改 owning YAML,并保持冷却保守;默认从一分钟开始,没有新证据和明确授权不得超过三分钟。
- YAML-managed 账号走
sync;runtime-manual 账号走显式runtime apply|delete。 - 多账号使用
--accounts精准集合;例外账号从 selector 中显式排除,不使用隐式全量操作。 - 先 dry-run 核对 change、before/after 和账号集合,再加
--confirm,最后逐账号get或批量 noop dry-run 对账。
- 非 auth 上游错误优先抽象为通用临时不可调度模板:
- 不把当前并发快照当作错误时并发:
- 只有错误原文明确指向 concurrency,或存在错误时历史并发证据,才把降低上游并发作为有界对照实验。
- 缺少直接证据时先处理主导上游根因。
- 下发后立即拉短窗口只做回归检查:
- 效果判定必须等待新的完整窗口。
- 同时比较请求分母、客户错误率、上游错误率、规则命中、切号成功、候选耗尽和 degraded 流式请求。
- 版本回退必须有源码差异或版本对照证据证明当前版本引入回归:
- 旧版具有同一选择或错误传播逻辑时,不用回退替代配置治理。
- 新版包含相关 failover 修复时,优先保留新版并治理真实根因。
- Codex pool 哨兵、账号冻结/恢复、marker-only 判断或 probe 周期看不清:第一步跑
bun scripts/cli.ts platform-infra sub2api codex-pool sentinel-report。这个报表是主观察面;只有报表缺字段或需要底层证据时,才继续看--raw、CronJob log、state ConfigMap 或 Sub2API 管理 UI。若看到“临时不可调度状态”且包含规则序号/匹配关键词,检查 Sub2APIaccount_temp_unschedulable日志和账号temp_unschedulable_*字段;sentinel 只解释schedulable=false的 active quarantine,不解释这类内置临时冷却。 - 只加强监控、不让哨兵自动冻结账号时,把 YAML
sentinel.actions.enabled=false后codex-pool sync --confirm。此时 marker probe 和 gateway failure monitor 仍记录would-freeze/ observe-only 证据,但不会通过 Sub2API admin 写schedulable=false;/responses/compact的codex.remote_compact.failed和 compact 上游 5xx failover 只作为gateway-compact-*观察事件记录,不作为哨兵自动切换触发器。 - 单个 request id 报 502/503/中断/没有自动切号:第一步跑
bun scripts/cli.ts platform-infra sub2api codex-pool trace --request-id <requestId>。先看outcome、reason、FAILOVER、SELECT-FAILED、ACCOUNT SIGNALS和WINDOW STATS;只有 trace 报表缺字段或需要审计原始日志时,才加--show-lines或--raw。若reason=failover-attempted-no-candidate,说明切号动作已发生,但 scheduler 在排除失败账号后没有可用候选;继续用sentinel-report和validate --full区分 sentinel quarantine、request-path temp-unschedulable、账号 status 或容量耗尽。 - profile invalid:先修
~/.codex/config.toml.<profile>的base_url、wire_api、model或auth.json.<profile>的 API key;不要在 YAML 中写密钥。 - 手动 OAuth/API-key 账号的 WebUI account test 连
chatgpt.com超时,但目标运行面显式 HTTP proxy 探针可通:不要只看 Pod 或容器环境变量,按“受保护手动账号代理与分组绑定”小节确认manualAccounts.protected[].proxyBinding,跑codex-pool sync --target <id> --confirm后再用原账号测试复测。若复测不再 reset/timeout,而是gpt-5.2-pro这类指定模型返回 ChatGPT OAuth Codex 不支持的能力错误,用默认/受支持模型或统一 key smoke 验证代理,不要把模型错误当作代理仍坏。 - 手动 OAuth/API-key 账号 WebUI account test 正常,但 PC Codex 客户端通过统一 key 访问
/responses返回 503 且 trace 是account-select-failed/no available accounts:按“受保护手动账号代理与分组绑定”小节确认该账号已绑定统一 key 使用的 pool group。WebUI group 列表和账号详情不一定足以证明 scheduler 可调度;必要时核对 admin account availability 与account_groupsjoin。k3s target 和 PK01 host-Docker target 都通过codex-pool sync --target <id> --confirm后用codex-pool validate --target <id> --full复测统一 key;如果MANUAL=N指向受保护手动账号缺失,先按账号所有权恢复或退役该手动账号,不把它混同为 YAML-managed pool 账号失败。 - pool key 401:跑
codex-pool sync --confirm重建 Sub2API key 与 k3s Secret 绑定,再跑codex-pool validate。 - pool key、admin password 或 k8s Secret
.data被 stdout、日志、issue 或本地 transcript 打印时,按泄露处理:撤销对应 Sub2API key 或 token,删除/重建受影响的 target Secret,通过codex-pool sync --target <id> --confirm或相应 YAML sourceRef 重新下发,再用 fingerprint、presence 和valuesPrinted=false作为 closeout 证据;不要复述旧值或新值。 - 运行中过去的验证探针残留:只用
codex-pool cleanup-probes --confirm清理unidesk-probe-*临时资源;不要把真实 managed account 删除当作探针清理或可用性恢复。 - default profile 递归:检查 YAML default entry 是否使用
*.pre-sub2api备份文件;必要时恢复备份后重新configure-local --confirm。 - 上游需要 WebSocket v2:先做 direct Codex WSv2 probe;通过后才给该 profile 配
openaiResponsesWebSocketsV2Mode: ctx_pool|passthrough并跑sync --confirm;把它当 capability candidate,容量仍以 YAML 中的capacity或默认值为准。 - Codex 启动 WebSocket 回退:用原入口 Codex smoke 复现,再用 bounded Sub2API 日志确认 account;对 WS handshake 4xx/5xx、
openai.websocket_account_select_failed或 close-before-response.completed的账号关闭 YAML WSv2 能力后同步。若没有剩余 WSv2-capable account,把localCodex.supportsWebSockets和localCodex.responsesWebSocketsV2一起关掉,不把临时可用性推断写成调度配置。 - 上游要求 Codex User-Agent:只给该 profile 配
upstreamUserAgent,跑sync --confirm。 - 上游报 capacity/rate-limit/overload/Bad Gateway/Gateway Timeout 后没有隔离或频繁先失败再恢复:先看
codex-pool sentinel-report的 marker、动作、冻结 TTL 和下一次 probe,也看codex-pool validate --full的 recent gateway failover/forward failure 证据;同时对照当前 Sub2API 源码里/v1/responseshandler、Forward、shouldFailoverOpenAIUpstreamResponse和handleOpenAIAccountUpstreamError的真实传播路径。不要手动禁用账号、删除账号、改 membership/priority/capacity/loadFactor 或从 YAML 移除问题账号来替代通用 failover 与哨兵隔离/恢复。 - Codex 报 weekly-limit、
less than 10% of your weekly limit left、Run /status for a breakdown等账号状态/软配额提示并要求切号:不要把新关键词写成 Sub2API 内置临时不可调度策略来恢复可用性;由 marker-only 哨兵按非 marker 响应统一冻结,并用sentinel-report/sentinel-probe验证。 - 上游 400/503 响应体出现
invalid_encrypted_content、bad_response_status_code、invalid_request_error+ 稳定 unsupported-model 文案、unsupported-model、暂不支持/可用模型、model_not_found、No available channel for model ...或同类稳定模型路由 / Responses encrypted-content 兼容性失败:按通用 temp-unschedulable/failover 加哨兵 marker 证据处理,不用 account membership、priority、capacity、loadFactor、WebSocket mode、User-Agent 或 provider pinning 掩盖该错误族。 - 上游错误反复触发:
invalid_encrypted_content、unsupported-model、Recovered upstream error ...、Bad Gateway、Gateway Timeout、Cloudflare524、Codex-facingUpstream request failed、Unknown error、context deadline exceeded、context canceled、model_not_found、No available channel for model、大上下文413和openai_error这类稳定包装文案,先确认 YAML temp-unschedulable 已同步、Sub2API 源码会把该错误族传播成UpstreamFailoverError、运行日志出现openai.upstream_failover_switching。若匹配规则后仍只看到openai.forward_failed,根因是 Sub2API HTTP/responses没把该错误传播成UpstreamFailoverError,应修 Sub2API failover classifier/error propagation,不硬编码账号或给only特权。 - Codex auto compact 后丢上下文:先确认 YAML
localCodex是否声明启用 WSv2;若启用,再确认本机~/.codex/config.toml是否有supports_websockets = true和responses_websockets_v2 = true,并看codex-pool validate的 WSv2 candidate 和 Sub2API 日志里的transport=responses_websockets_v2。若 YAML 当前禁用 WSv2,则按 HTTP Responses 稳定性排查,不把旧 WS 口径当成验收要求。 - Codex smoke 有 reconnect/1013:这是上游并发/可用性问题,和 HTTP-only compact context-loss 分开处理;记录 session/log 证据并关联专项 issue,不要用运行时手补覆盖 YAML 容量。