从症状出发排障
排障的第一步永远是拿到 z-request-id——它是贯穿客户端、网关、上游、日志的唯一线索。
先拿到 z-request-id
每个请求的响应头里有 z-request-id(格式 <iso8601>-<uuid4>)。客户端报错时,让客户端把响应里的这个头给你。
拿不到响应头时
客户端在收到响应前就失败了(连接被拒、TLS 失败)时没有 z-request-id——这种是网关没收到请求或收到前就断,从网关侧日志查不到,先查网络层(端口、防火墙、反代)。
进控制台 → 日志页,在搜索框粘上这个 ID 即可定位。日志详情含完整请求/响应生命周期,见 导出账单 Excel 与日志排查 的「实战:定位客户端问题」。
客户端报 401 / 403
| 状态码 | error_type 常见值 | 含义 | 处理 |
|---|---|---|---|
| 401 | authentication_error | 没带访问密钥或密钥无效/被禁用 | 检查 Authorization: Bearer 后跟的是你签发的访问密钥(不是上游 sk-...);密钥是否被禁用 |
| 403 | model_access_denied | 密钥所在密钥组的 models 列表没含该模型 | 回密钥组把模型加进去(或 *) |
| 403 | model_access_denied | 密钥组的 load_balancers 没含该 LB | 回密钥组「负载均衡器」子页签勾选(* 不含 LB) |
| 403 | ip_banned | IP 被封禁(连续登录失败触发) | 等几分钟(默认 300 秒)自动解封 |
403 的 LB 维度是最常见的配错点,见 多租户隔离。
客户端报 404
model_not_found:模型名拼错,或该模型被设了hide_name(只能用别名访问)。见 上游与模型字段 的「隐藏主名」。- 别名 vs 规范名:密钥组
models只匹配规范名,不解析别名。
客户端报 502 / 503
| 状态码 | 来源 | 处理 |
|---|---|---|
| 502 bad_gateway | 上游不通或返回非预期 | 检查上游 base_url、API key、上游可达性 |
| 503 | 所有节点不可用(LB 重试预算耗尽)/ 网关排空(drain) | LB 场景检查每个 entry 的上游;排空是正常下线 |
503 持续不停 = 所有节点都挂,检查每个上游。Bedrock 场景注意填的是 Bedrock API key 不是 IAM key,见 接入 AWS Bedrock。
请求很慢或超时
- 客户端超时但上游正常:检查
UPSTREAM_SEND_TIMEOUT_SECS(发请求体+等响应头,默认 180)/UPSTREAM_READ_TIMEOUT_SECS(单块读,默认 600)。整个上游生命周期还有一道 3600 秒的硬上限(固定,不通过环境变量开放)。见 环境变量配置参考。 - 上游本身就慢(推理模型长思考):调大
UPSTREAM_READ_TIMEOUT_SECS,它每块重置。 - 跨境上游僵尸连接:跨境建议调短反代/上游侧的 keepalive;该 TCP keepalive 参数未通过环境变量开放,有需要请联系支持。
流式中途断掉
- 首块发出后上游断:不换节点,记录
body_incomplete,已收部分返回客户端。 - 网关侧超时:
STREAMING_KEEPALIVE_SECONDS(默认 15)发 SSE:keep-alive,需短于反代空闲超时(Nginx 默认 60)。反代超时太短会切断长流。 - 流式时长或空闲超上限:
MAX_STREAM_DURATION_SECS(默认 3600)是单流总时长上限,STREAM_IDLE_TIMEOUT_SECS(默认 600)是两块间空闲上限,超过即断流。
网关内存异常升高
- 大 body 场景用了 after 槽脚本做纯路由决策:改用
switch-route规则。见 脚本性能与内存 的反模式。 max_request_size_mb/max_response_body_mb设得过大:多模态大对话占内存。- 内存门(memory gate)触发 429:调
memory_soft_limit_mb或检查是否有异常大的突发流量。
还定位不了怎么办
常见问题
Q:日志里找不到这个 z-request-id? 可能请求没到网关(网络层断),或在 401 早期失败阶段(未持久化)。检查客户端是否真连到了网关端口。
Q:错误体格式是什么样的? 三种格式(取决于客户端协议与错误阶段),见 错误码速查。
