首页/AI/大模型部署与运维速查/Nginx 反代 SSE:流式不缓冲

Nginx 反代 SSE:流式不缓冲

流式接口经 Nginx 常见坑是响应被缓冲:需要关闭 proxy_buffering、使用 HTTP/1.1、放宽读超时,并把到上游的连接头清空以复用长连接。

反代 SSE 要注意什么

流式接口(SSE)经 Nginx 反代最常见的坑是响应被缓冲:Nginx 默认会先攒数据再转发,流式因此退化成一整块返回。要按顺序处理几件事:关闭响应缓冲与缓存、使用 HTTP/1.1、放宽读超时,并清空到上游的连接头以复用长连接。任何一项漏掉,前端的首字体验都不会改善。

基本信息

关键指令proxy_buffering off、proxy_cache off、proxy_http_version 1.1
长连接proxy_set_header Connection "" 以复用上游连接
超时proxy_read_timeout 需大于最长生成时间
适用Nginx 反代任意 OpenAI 兼容端点
前置条件后端本身支持流式响应

典型使用场景

  • 在推理服务前加一层 Nginx 做负载均衡与 TLS 终结
  • 修复「开了流式但内容一次性出现」的问题
  • 长回答在某处被切断:核对读超时与中间层连接策略
  • 多实例后端下的流式分流:确认切换实例时连接处理正常
  • 链路上叠加 CDN 或企业代理时逐层确认是否还有缓冲

关键 location 配置

关键 location 配置
location /v1/ {
    proxy_pass http://127.0.0.1:8000;
    proxy_http_version 1.1;        # SSE 依赖长连接
    proxy_buffering off;           # 不做响应缓冲
    proxy_cache off;               # 流式响应不要缓存
    proxy_read_timeout 600s;       # 要大于最长生成时间
    proxy_set_header Connection ""; # 清空连接头以复用上游长连接
}

验证流式是否真的生效

验证流式是否真的生效
# -N 关闭 curl 自身缓冲:观察内容是否逐块到达
curl -N -H "Authorization: Bearer <KEY>" \
  -H 'Content-Type: application/json' \
  -d '{"model":"<模型名>","messages":[{"role":"user","content":"数到二十"}],"stream":true}' \
  http://<网关地址>/v1/chat/completions

# 逐块滚动出现即为正常;整段一次性出现说明链路上仍有缓冲

配置项与漏配表现

配置项作用漏配的表现
关闭响应缓冲数据到达即转发内容被攒成一整块
使用 HTTP/1.1支持长连接与分块传输连接复用异常、流被中断
放宽读超时容纳长输出长回答说到一半断流
清空连接头正确复用上游连接上游连接反复重建,延迟升高
超时按生成时长设置:长输出场景的读超时要大于最长生成时间,否则流会在中途被切断,表现为内容不完整。
对事件流类型启用压缩(gzip 等)会引入聚合行为:中间层需要攒够数据才能压缩,流式体验随之退化,建议对流式路径关闭压缩。

易错点

  • 只改一层:CDN 或企业代理仍会缓冲,表现为流式「一块块来」或整段等待
  • 沿用默认读超时:长回答在网关层被切断,日志里只有一条上游超时记录
  • 没清空到上游的连接头:长连接复用异常,偶发流中断且难以复现
  • 对流式路径开启压缩:中间层为压缩而聚合数据,等于把缓冲又加了回来

数据来源与参考

  • Nginx 官方文档:proxy_buffering(nginx.org/en/docs)
  • vLLM 官方文档:流式与代理注意事项(docs.vllm.ai)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌