nginx代理sse卡顿的核心原因是默认启用proxy_buffering,导致数据积压不实时转发;必须在location中设proxy_buffering off,并配proxy_read_timeout 3600s+、proxy_http_version 1.1、proxy_set_header connection ''、proxy_cache off等协同配置。

Nginx 代理 SSE 时卡顿和延迟,核心不是后端没发,而是 Nginx 挡在中间“攒着不发”。默认配置把流式响应当成普通请求处理,等数据积满或超时才吐给前端,自然就没了打字机效果。关键在于让 Nginx 放弃缓冲、保持连接、按需转发。
必须关闭 proxy_buffering
这是最直接的开关。只要它开着,Nginx 就会把后端逐块输出的 SSE 数据先收进缓冲区,直到凑够大小(比如 4KB)或超时才一次性发出去。前端看到的就是几秒后突然刷出一大段,而不是实时逐行接收。
- 在对应 location 块里加
proxy_buffering off; - 不要全局关,只针对
/sse、/chat、/events这类流式路径单独设置 - 这一行没加,其他配置全白搭
延长并协调超时时间
SSE 连接本就不该频繁断开。Nginx 默认 proxy_read_timeout 60s,一旦后端 60 秒内没新数据(比如用户暂停输入),Nginx 就主动断连,前端触发重连,造成卡顿感甚至消息丢失。
- 设置
proxy_read_timeout 3600s或更长(如86400s),匹配业务预期的最长空闲时间 - 同步调整
proxy_send_timeout,避免发送阶段被意外中断 - 注意:超时值不是越大越好,要结合后端心跳机制(如定期发
:\n注释)和负载情况权衡
确保使用 HTTP/1.1 并透传连接升级头
SSE 依赖 HTTP/1.1 的持久连接与分块传输。Nginx 默认可能回落到 HTTP/1.0,导致连接反复建立,破坏流式连续性。
- 加
proxy_http_version 1.1; - 加
proxy_set_header Connection '';(清空 Connection 头,避免干扰) - 若后端是 WebSocket 或需要协议升级,还需
proxy_set_header Upgrade $http_upgrade;和proxy_set_header Connection "upgrade";
关闭缓存与压缩,避免干扰流式语义
SSE 响应是动态、不可复用的实时事件流,缓存或 gzip 压缩会引入额外延迟,甚至破坏 chunk 边界。
proxy_cache off;gzip off;- 可选但推荐:
add_header X-Accel-Buffering no;显式告知 Nginx 不要缓冲(部分版本更可靠)
补充建议
-
chunked_transfer_encoding on;保持开启,它本身是流式传输的基础机制,不是问题根源 - 避免在 location 中写
localhost作 proxy_pass 目标,改用127.0.0.1或域名,防止 DNS 解析拖慢首字节时间 - 检查后端是否设置了合适的响应头:
Content-Type: text/event-stream、Cache-Control: no-cache、Connection: keep-alive
配完 reload nginx,用 curl 测试:curl -N http://your-domain.com/sse-endpoint
应该能看到数据一行行即时打印,而不是停顿数秒后集中输出。











