关闭 proxy_buffering 是流式场景实时推送的底线配置,需同步禁用 proxy_cache、设小缓冲区、启用分块传输、调高超时值,并确保后端与客户端协同支持。

直接关掉 proxy_buffering 是最有效、最必要的一步。它不是“可选优化”,而是流式场景(SSE、AI 打字机、Server-Sent Events、Fetch Stream)能实时推送的底线配置。
为什么 proxy_buffering on 会导致严重延迟
Nginx 默认开启代理缓冲,意味着它会等后端响应攒够一定量(比如几 KB),才一次性转发给客户端。这对普通网页加载友好,但对逐字/逐 event 推送完全不适用:
- 后端已生成并写出第一个
data: hello,Nginx 却把它扣在内存里等更多数据 - 用户看到首字延迟常达 3–10 秒,甚至更久
- 连接可能因长时间无输出被中间设备(如 CDN、防火墙)静默断开
关键配置项必须同步设置
仅关 proxy_buffering 不够,还需配套关闭其他隐性缓存和干扰机制:
-
proxy_cache off:防止 Nginx 把流式响应误判为可缓存内容 -
proxy_buffer_size 4k和proxy_buffers 8 4k:不追求大缓冲,保持小而快;避免设成 1k 过小引发频繁系统调用 -
proxy_busy_buffers_size 8k:匹配缓冲区总容量,避免写入阻塞 -
proxy_hide_header X-Accel-Buffering+add_header X-Accel-Buffering no:显式告诉浏览器“本响应不缓冲”,绕过某些浏览器的启发式缓冲策略 -
chunked_transfer_encoding on:确保响应使用分块传输,这是流式输出的 HTTP 基础
超时与连接头不能忽略
流式连接是长连接,常规超时值会中断推送:
-
proxy_read_timeout 300或更高(如 86400):控制 Nginx 等待后端响应的最长时间,SSE 场景中后端可能几十秒才发下一个 event -
proxy_send_timeout 300:控制 Nginx 向客户端发送响应的超时,防止网络慢导致假死 -
proxy_http_version 1.1:必须启用,HTTP/1.0 不支持持久连接和 chunked -
proxy_set_header Connection '':清空 Connection 头,避免上游或中间层误加keep-alive或close干扰
后端与客户端也要配合
Nginx 配置只是链路一环,两端需协同:
-
后端(如 SpringBoot):确保返回
Content-Type: text/event-stream,禁用框架级响应缓冲(如 Tomcat 的bufferSize、Spring WebMvc 的ResponseBodyEmitter写入前 flush) -
客户端(如 EventSource):监听
message事件而非open,每次收到data:就立即处理,不要攒 batch -
验证方式:用
curl -N http://your-domain/api/events直接看原始输出节奏,首行出现时间应 ≤ 500ms











