[Bug] AI Gateway Fails to Reconnect After Upstream Connection Becomes Unresponsive
メンテナーはふだん 1 日以内に返信
@wanghe-fit2cloud がすでに取り組んでいます。
2026年10月19日 から。
評価
この issue はまだ評価されていません。
説明
Contact Information
No response
1Panel Version
v2.1.13(Kylin Linux Advanced Server V10,Docker 部署)
AI Gateway 应用版本:v1.2.0
镜像:1panel/ai-gateway@sha256:8a5ada1094609c281f6a99383339e37b4958e4a2d26eb9921f1d8dd1b8283792
Problem Description
AI Gateway 在一条上游 HTTP/2 长连接失效后,会持续复用这条已不可用的连接,导致所有模型、所有协议的请求一起超时;直到 Linux 内核 TCP 重传耗尽(约 16 分钟)或重启容器后才恢复。
环境与配置
- 1Panel:v2.1.13,Kylin Linux Advanced Server V10
- AI Gateway:v1.2.0,Docker 部署
- 单个上游账号:DeepSeek,
https://api.deepseek.com - 同时启用三种协议:
openaiChatCompletions→/chat/completionsopenaiResponses→/responsesanthropicMessages→/anthropic/v1/messages
- 模型映射:
deepseek-flash、deepseek-v4-flash、deepseek-v4-pro→deepseek-flash
影响
2026-10-19 当天出现两次(CST):
- 第一次约 15:35 开始,重启
1Panel-ai-gateway-*****容器后恢复; - 第二次 17:44 开始,未重启,17:59:52 自行恢复。
故障期间容器状态 healthy,CPU 0.12%、内存 55.8MiB,进程未崩溃、无重启;但三种协议的所有推理请求都卡住或超时。新建上游连接完全正常,说明不是密钥、模型名或协议转换问题。
关键证据
- 故障期间容器内只有一条上游连接,且已无 ACK、无新数据:
$ nsenter -t <gateway-pid> -n ss -ntip dst :443
ESTAB 0 522781 172.18.0.11:45450 171.105.220.186:443
cubic rto:120000 backoff:15 cwnd:1
bytes_sent:4474356 bytes_acked:4451789
lastrcv:895584 lastack:895580
unacked:11 retrans:1/20 lost:11
notsent:508248
Send-Q 积压约 511KB,lastrcv / lastack 已停滞约 895 秒,RTO 退避到 120 秒;该连接持续重传,但收不到任何 ACK 或数据。
- 同一时间、同一容器网络内,新建连接访问
api.deepseek.com解析出的 4 个 IP(包括故障连接的对端171.105.220.186)全部正常:
171.105.220.186 HTTP/2 200 first=0.023s total=0.647s
171.108.213.114 HTTP/2 200 first=0.021s total=0.787s
171.108.215.12 HTTP/2 200 first=0.023s total=0.714s
171.108.216.18 HTTP/2 200 first=0.023s total=0.725s
HTTP/1.1 也同样正常,说明上游服务、DNS 和出网链路对新连接均可用,故障只存在于被复用的旧 TCP 流。
- 旧连接消失后网关立即恢复:
17:59:34 旧连接仍在,Send-Q 522781,请求超时
17:59:52 旧连接消失(conns=0)
17:59:52 下一次请求 HTTP 200,0.76 秒
新连接 172.18.0.11:40516 -> 171.105.220.186:443(fd=17)
未重启容器、未修改配置,仅因为内核最终放弃旧 TCP 连接,网关就自动新建连接并恢复。
- 时间线:
| 时间(CST) | 事件 |
|---|---|
| 17:43:57 | 最后一次正常收到上游数据 |
| 17:43:59 | 首个失败请求,120 秒后报 upstream_unavailable |
| 17:44–17:59 | 后续请求全部超时或被客户端取消 |
| 17:59:52 | 旧连接被内核拆除,下一次请求立即 200 |
从最后一次收到数据到恢复约 15 分 55 秒,与 tcp_retries2=15、RTO 上限 120 秒的表现吻合。
- 相关配置:
gateway.request_timeout_seconds = 120
gateway.stream_idle_timeout_seconds = 120
gateway.max_concurrency = 10
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_retries2 = 15
网关设置中未发现 HTTP/2 保活相关配置项;从实际表现看,120 秒的请求超时并没有触发连接关闭或重建。
- 网关日志:
time=2026-10-19T09:45:59.796Z level=WARN
msg="upstream attempt failed"
request_id=608f6e0f90f684016bea78d717dec2ae
stage=send_attempt reason=timeout account_id=1 request_written=true
除该 WARN 外,没有 panic、goroutine 堆栈或连接重建日志。
根因分析(推测)
- 17:44 左右,一条到上游的 TCP 流进入黑洞状态:没有 ACK、没有新数据,但连接仍保持
ESTAB。 - 网关没有及时识别这条共享连接已不可用,后续所有请求继续复用它。
request_timeout/stream_idle_timeout只结束单次请求,不会关闭底层连接;TCP keepalive 为默认 7200 秒,HTTP/2 保活疑似未启用。- 最终只能等 Linux 按
tcp_retries2=15放弃 TCP 连接,导致单次网络异常放大为约 16 分钟的全局不可用。 - 当前只有一个上游账号,三种协议共用同一个 host 连接池,因此一条死连接会影响所有模型和所有协议。
需要说明:上游 TCP 流为何在 17:44 变成黑洞,现有证据无法确定是上游侧还是中间网络触发;但网关在连接失效后的恢复策略不够快,这是可以改进的部分。
Steps to Reproduce
该问题为偶发,生产环境未主动执行破坏性复现。建议在测试环境用以下方式稳定复现:
- 部署 AI Gateway v1.2.0,配置一个 DeepSeek 上游账号及上述三种协议;
- 发起一次正常请求,确认上游连接建立;
- 在容器网络命名空间中找到该连接的 4 元组;
- 只对该 4 元组临时下发 DROP 规则(仅测试环境),模拟 TCP 黑洞;
- 继续发起请求,观察网关是否持续复用旧连接、是否在 120 秒超时后重建;
- 预期可复现“新连接正常、旧连接上的所有请求持续超时,直到 TCP 重传耗尽或容器重启”。
The expected correct result
- 上游请求超时(尤其是
send_attempt/request_written=true后无响应)时,应将对应连接标记为不可用并主动关闭,而不是继续放回连接池; - 为上游 HTTP/2 连接启用保活(如
ReadIdleTimeout/PingTimeout),或设置合理的TCP_USER_TIMEOUT,让失效连接在几十秒内被发现; - 连接失效后,新请求应能自动新建连接;对幂等请求可考虑在新连接上重试一次;
- 增加“连接被丢弃/重建”的日志,便于定位此类问题;
- 如果存在多个上游账号,建议支持连接级故障转移。
Related log output
time=2026-10-19T09:45:59.796Z level=WARN msg="upstream attempt failed" request_id=608f6e0f90f684016bea78d717dec2ae stage=send_attempt reason=timeout account_id=1 request_written=true
调用日志摘要:
17:43:59 deepseek-flash duration=120084ms error=upstream_unavailable
17:46:00 deepseek-flash duration=500198ms error=request_canceled
17:51:01 deepseek-flash duration=29989ms error=request_canceled
17:51:03 deepseek-flash duration=199735ms error=request_canceled
17:55:33 deepseek-flash duration=11718ms error=request_canceled
Additional Information
- 容器未暴露 pprof / 调试端口,故障期间未能采集 goroutine 堆栈;以上判断基于 TCP 状态、调用日志和恢复过程。
- 已检索公开 issue,未发现与本问题完全一致的记录;#14035 是高并发 503,#13965 是双认证头 401,均不能解释本次“旧连接卡死、新连接正常、重启或连接拆除后立即恢复”的现象。
- 当前运行 v1.2.0;v1.4.0 发布说明未明确提到该连接复用/失效重建问题,升级后我们会继续验证并补充结果。
- 以上日志和 IP 已做脱敏,未包含密钥;如需更多现场数据可以继续提供。
- 主要言語
- Go
- スター
- 37.2k
- フォーク
- 3.4k
- 平均マージ
- 11時間 43分
- マージ済み PR(30日)
- 84
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
1Panel-dev/1Panel のほかの issue
-
[Feature] Is it possible to enrich AI Gateway functionality対応中かも @wanghe-fit2cloud が 1 日前に担当しました。 オープンtype: ai-gateway
1Panel-dev/1Panel#14135 · コメント 1 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
[Bug] 数据库mysql対応中かも @wanghe-fit2cloud が 1 日前に担当しました。 オープン
1Panel-dev/1Panel#14131 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
[Bug] Professional Edition License Cannot Be Activated対応中かも @wanghe-fit2cloud が 1 日前に担当しました。 オープンtype: question
1Panel-dev/1Panel#14130 · コメント 1 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
[Bug] Incompatibility with TencentOS when installing third-party software対応中かも @wanghe-fit2cloud が 1 日前に担当しました。 オープンtype: optimization
1Panel-dev/1Panel#14128 · コメント 1 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
[Feature] Runtime should stop the container only after ensuring the image pull is complete.対応中かも @wanghe-fit2cloud が 1 日前に担当しました。 オープンtype: optimization
1Panel-dev/1Panel#14126 · コメント 1 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
1Panel-dev/1Panel の issue をすべて見る
似ている issue
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
Rafaeldelinares/gentle-mesh#125 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
Gentleman-Programming/gentle-ai#5643 ·
メンテナーはふだん 1 日以内に返信
-
security
難易度 2/5 1〜3時間 初心者へのやさしさ 80/100
FootprintAI/Containarium#2869 ·
メンテナーはふだん 1 日以内に返信
-
kind/bug
難易度 2/5 1〜3時間 初心者へのやさしさ 86/100
kubevirt/kubevirt#19559 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
-
bug raised-by:verifier
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
medici-finance/assay#3817 ·
メンテナーはふだん 1 日以内に返信