Nginx 反代 SSE 流式接口:gzip 压缩与 proxy_buffering 的冲突与解法

举报
yd_245773411 发表于 2026/10/24 00:11:48 2026/10/24
【摘要】 大模型 API 面板普遍 1MB 起步,不压缩在国内访问极慢;但开了 gzip 又常常把 SSE 流式接口卡死。本文用一个真实的双入口配置说明 gzip、proxy_buffering、proxy_read_timeout 三者如何按 location 分开设置,既保住首屏又不断流。

问题背景

把大模型 API 的中转面板部署在新加坡的机器上,国内打开一个 1MB 的单页应用,晚高峰经常卡到 40 秒以上,甚至直接超时。服务端日志看不出问题,curl 本机测又是 0.05 秒返回,很容易误判成"服务挂了"。

真正的原因有三个叠加:页面单文件接近 1MB、Nginx 没有开 gzip、跨境链路 RTT 高。开了 gzip 之后首屏问题解决了,但新的坑马上出现——同一个 Nginx 里的 SSE 流式接口开始"只返回第一个字就停住"。

为什么 gzip 会卡死 SSE

SSE(Server-Sent Events)依赖 text/event-stream 长连接,数据是一小块一小块推给客户端的。而 gzip 压缩需要攒够缓冲区才会输出,gzip_proxied 与 proxy_buffering 同时开启时,Nginx 会把上游的碎片响应先缓冲再压缩,客户端感知到的就是"卡住不动"。

结论很直接:压缩和流式不能放在同一个 location 里。静态页面要缓冲 + 压缩,SSE 接口要关闭缓冲、关闭压缩。

配置拆成两个 location

gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml;

# 首页:整页缓冲 + 压缩
location = / {
    proxy_pass http://127.0.0.1:8789;
    proxy_buffering on;
    proxy_buffers 32 64k;
    proxy_buffer_size 128k;
    proxy_busy_buffers_size 256k;
    proxy_set_header Accept-Encoding "gzip";
}

# API:保留流式,不缓冲
location /v1/ {
    proxy_pass http://127.0.0.1:8789;
    proxy_buffering off;
    proxy_cache off;
    proxy_read_timeout 600s;
    proxy_set_header Connection "";
    chunked_transfer_encoding on;
}

实测首页从 1,007,540 字节压到 298,643 字节,约 1/3.4,国内首屏时间从 40 秒降到可接受范围;/v1/chat/completions 的 stream:true 首字节仍然正常返回,SSE 没有受影响。

几个容易踩的细节

  • gzip_comp_level 不要盲目上 9,对 1MB 的文本 9 和 6 只差几 KB,但 CPU 占用翻倍;机器核数少时优先 6。
  • 只有 gzip_types 里列出的类型才会压缩,text/html 默认就压,别重复写。
  • 上游如果自己已经返回 Content-Encoding: gzip,Nginx 默认不会再压一遍,注意别双重压缩。
  • proxy_read_timeout 对 SSE 必须放大,默认 60 秒会把长回答直接掐断。
  • 改完一定先 nginx -t 再 reload,配置语法错误会让整个站点 502。

如何验证

不要只在本机 curl。本机到服务端是内网,永远快。要在真实客户端侧测:

curl -o /dev/null -H 'Accept-Encoding: gzip' \
  -w 'http=%{http_code} connect=%{time_connect}s ttfb=%{time_starttransfer}s size=%{size_download}\n' \
  https://example.com/

对比 size_download 是否明显变小、time_starttransfer 是否下降;SSE 则用 curl -N 看数据是否持续输出而不是攒一大块。

小结

跨境部署的面板类服务,性能问题往往不在代码而在传输层:先量体积,再开压缩,最后按路径区分缓冲策略。压缩与流式分开配置,是这套组合里性价比最高的一步。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。