直接答案
“超时”不是一个层级:连接尚未建立、已连接但无首字节、流中断和客户端总时限需要不同修复。
这篇内容解决什么问题
解决 API 请求超时、ETIMEDOUT、context deadline exceeded 和长时间无响应。
先确认症状与影响范围
客户端报告 timeout、ETIMEDOUT、context deadline exceeded 或长时间没有首个 Token。部分 SDK 只显示统一异常,需要结合耗时阶段和代理日志判断。
连接超时发生在 TCP/TLS 建立前;首字节超时发生在请求已发送后;流式空闲超时则发生在已经收到事件之后。
- 记录 DNS、连接、TLS、首字节和总耗时,而不是只有总时长。
- 比较模型列表、最小非流式、最小流式与完整请求。
- 确认超时来自 SDK、反向代理、负载均衡器还是上游服务。
常见原因与责任边界
客户端、企业代理、CodeNodex 网关和模型上游都可能设置时限。简单增大全局 timeout 会掩盖坏连接并长期占用资源。
- DNS、TCP 或 TLS 建连缓慢或失败。
- 长上下文、复杂工具或模型排队导致首字节时间增加。
- 代理的 read/idle timeout 小于模型生成间隔。
- 连接池耗尽、并发过高或客户端总 deadline 太短。
按层执行最小诊断
使用 curl timing 拆分连接与首字节阶段,再用最小非流式请求验证模型处理。只有长请求超时时,缩短上下文和输出上限做对照。
流式请求收到部分事件后超时,应继续检查 SSE 页面,不要把已产生的部分输出当作完整成功。
- 01测建连记录 DNS、TCP、TLS 时间,确认网络路径是否稳定。
- 02测首字节用最小非流式请求记录 time_starttransfer。
- 03测生成比较短输入与真实输入、短输出与长输出。
- 04对齐时限检查 SDK、代理和作业总 deadline 的最短一层。
curl -sS -o /tmp/timeout-body.json --connect-timeout 10 --max-time 60 -w 'dns=%{time_namelookup} connect=%{time_connect} tls=%{time_appconnect} first=%{time_starttransfer} total=%{time_total} status=%{http_code}
' 'https://<your-api-host>/v1/models' -H "Authorization: Bearer ${API_KEY:?set API_KEY first}"针对根因完成修复
分别设置连接、首字节/读取和作业总时限。改善上下文、并发和连接复用后,再按真实模型延迟调整合理阈值;不要使用无限 timeout。
- 01设置分层时限连接时限较短,读取与总时限按模型和任务预算设置。
- 02控制负载限制并发、复用连接并避免连接池饥饿。
- 03缩减请求移除无关上下文,限制输出并拆分超长任务。
- 04安全重试仅在未产生副作用且可判断失败阶段时有限重试。
connect_timeout = 10s
read_or_idle_timeout = 90s
overall_job_deadline = 120s
retry_attempts = 2
# 数值仅为示意,应以真实模型延迟、代理限制和业务 SLO 校准。验证修复而不是只看一次成功
在短请求、长请求和并发场景分别验证 P50/P95 首字节与总耗时。超时发生时应明确是哪一预算到期,并能取消仍在运行的请求。
- 连接、首字节、流式空闲和总 deadline 分开可观测。
- 取消请求会释放连接与 worker。
- 重试不会导致重复输出、重复动作或无限等待。
安全边界与升级证据
不要通过关闭 TLS 检查、无限放大时限或把请求全文写入 APM 解决超时。支持材料应使用脱敏的 timing、状态码、模型和 request ID。
- 诊断日志不记录 Key 与用户消息。
- 所有请求有明确可取消的总 deadline。
- 代理时限变更经过容量评估。
官方来源与核验范围
本文以协议规范和客户端官方文档为事实依据。错误文案、重试头和配置字段可能随服务或客户端版本变化;执行前请核对来源,并对日志与请求样例脱敏。
查看技术核验方法