← 返回航标笔记
#接入指南#排障

流式输出中途断开:SSE 停流的六个排查位置

研究桌上的服务模块、资料清单与放大镜,呈现 API 服务选型中的证据比对

首字正常、几秒后断流,是最难定位的一类故障。把链路拆成客户端、代理、中转、上游四段,逐段确认谁先超时。

流式输出断开的典型表现是:第一段内容正常返回,几秒后连接被重置,客户端提示网络错误但服务端日志里只有一条 200。这类问题极少来自模型本身,多数发生在链路的超时设置上。

第一处要看客户端。多数 HTTP 库默认读取超时是 30 秒或 60 秒,而一次长回答可能持续两分钟。把读取超时改成按数据块计算,也就是只要还在收到 chunk 就继续读,断流会明显减少。

第二处是自建代理。Nginx 默认 proxy_buffering 开启,会先缓存上游数据再转发,长连接下容易触发 proxy_read_timeout。需要关闭缓冲并把读超时提升到 300 秒以上,同时确认没有开启 gzip 二次压缩,压缩会打乱 SSE 的分块边界。

第三处在中转站一侧。中转如果把上游流转换成普通响应再逐条推送,本身就会引入额外延迟;如果它设置了固定的整体超时(例如 120 秒),长回答必然被切断。这类问题只能通过对比直连与中转的同一请求耗时来确认。

第四处是上游模型的 max_tokens。部分站点会把请求里的 max_tokens 截断到一个较小值,回答在到达上限时正常结束,客户端却把它当成异常断开。检查响应里的 finish_reason 是不是 length,是判断依据。

排查顺序建议从外到内:先用 cURL 直接请求中转,排除客户端;再用中转请求官方端点,排除中转;最后替换成短问题,排除长度因素。三段都正常,问题通常就在本地网络与连接复用上,例如启用了 HTTP/2 连接池但中途被中间设备回收。