Nginx反向代理流式输出延迟?一招解决SSE/WebSocket缓冲问题SpringBoot+SSE流式输出卡住?Nginx这个配置必须关!

Nginx反向代理流式输出延迟?一招解决SSE/WebSocket缓冲问题

SpringBoot+SSE流式输出卡住?Nginx这个配置必须关!

Nginx代理后端流式响应要等好久才输出?完整解决方案来了

AI对话流式输出卡顿?Nginx proxy_buffering关闭指南

宝塔面板Nginx配置流式输出,90%的人都漏了这行配置

一、问题描述

最近在项目中使用 SpringBoot + SSE(Server-Sent Events) 实现流式输出功能(类似ChatGPT的打字机效果),发现前端接收数据时有明显延迟,需要等后端积累好多字才会输出一次,而不是实时逐字输出。

现象:

  • 后端已经返回数据,但前端迟迟收不到

  • 需要等待几秒甚至更久才一次性输出一大段

  • 流式效果完全失效,用户体验极差

环境:

  • Nginx 反向代理

  • 后端:SpringBoot

  • 协议:SSE / 流式响应

二、问题原因

Nginx 作为反向代理时,默认会开启响应缓冲(proxy_buffering),它会等后端响应达到一定大小后,才一次性发送给客户端。这对于普通HTTP请求没问题,但对于流式输出就是灾难。

核心原因:

Nginx 默认缓冲 → 数据积累到缓冲区阈值 → 才发送给客户端

三、解决方案

3.1 关键配置

在 Nginx 的 location 块中添加以下配置:

复制代码
location ^~ /jeecg-boot {
    proxy_pass              http://127.0.0.1:9191/jeecg-boot/;
    proxy_set_header        Host  $ Host;
    proxy_set_header        X-Real-IP  $ remote_addr;
    proxy_set_header        X-Forwarded-For  $ proxy_add_x_forwarded_for;
    proxy_set_header        Upgrade  $ http_upgrade;
    proxy_set_header        Connection "upgrade";
    
    # ⭐ 流式输出核心配置 ⭐
    proxy_buffering off;           # 关闭代理缓冲(最重要!)
    proxy_cache off;               # 关闭缓存
    proxy_request_buffering off;   # 关闭请求缓冲
    chunked_transfer_encoding on;  # 启用分块传输
    
    # 可选:设置较小的缓冲尺寸
    proxy_buffer_size 1k;
    proxy_buffers 4 1k;
    proxy_busy_buffers_size 2k;
    
    # 超时设置(防止长连接断开)
    proxy_connect_timeout 60s;
    proxy_send_timeout 300s;
    proxy_read_timeout 300s;
}

3.2 配置说明

配置项 作用 是否必须
proxy_buffering off 关闭响应缓冲,实时转发 ⭐ 必须
proxy_cache off 关闭缓存 推荐
proxy_request_buffering off 关闭请求缓冲 推荐
chunked_transfer_encoding on 启用分块传输编码 推荐
proxy_read_timeout 延长读取超时时间 长连接必须

四、后端配合配置

4.1 SpringBoot SSE 响应头

后端也需要设置正确的响应头,否则Nginx配置了也没用:

复制代码
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<String>> stream() {
    return Flux.interval(Duration.ofMillis(100))
        .map(sequence -> ServerSentEvent.builder("数据:" + sequence)
            .build());
}

关键响应头:

复制代码
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
X-Accel-Buffering: no

4.2 普通流式响应

复制代码
@GetMapping("/flow")
public void flow(HttpServletResponse response) throws IOException {
    response.setContentType("text/plain;charset=utf-8");
    response.setHeader("Cache-Control", "no-cache");
    response.setHeader("Connection", "keep-alive");
    response.setHeader("X-Accel-Buffering", "no");  // 关键!
    
    ServletOutputStream out = response.getOutputStream();
    for (int i = 0; i < 10; i++) {
        out.write(("数据" + i + "\n").getBytes(StandardCharsets.UTF_8));
        out.flush();  // 必须flush
        Thread.sleep(100);
    }
}

七、常见问题排查

7.1 配置后仍然有延迟?

  1. 检查是否有CDN:CDN也会缓冲,需要单独配置
  2. 检查Gzip:流式内容建议关闭gzip
  3. 检查后端是否flush :确保后端每次写入后都调用了flush()

7.2 连接频繁断开?

增加超时时间,并检查防火墙设置:

复制代码
proxy_send_timeout 600s;
proxy_read_timeout 600s;
keepalive_timeout 600s;

7.3 WebSocket也适用吗?

适用!WebSocket同样需要关闭缓冲,配置基本一致。

八、总结

表格

场景 关键配置
SSE流式输出 proxy_buffering off
WebSocket proxy_buffering off + Upgrade头
大文件下载 proxy_buffering off
AI对话流式 proxy_buffering off + 后端flush

核心就一行:proxy_buffering off;

但别忘了后端配合设置响应头和flush,否则还是不会实时输出!

九、参考资料


如果对你有帮助,欢迎点赞👍 收藏⭐ 关注💖

有问题欢迎在评论区留言讨论!

相关推荐
开开心心就好2 小时前
内存清理软件灵活设置,自动阈值快捷键清
运维·服务器·windows·pdf·harmonyos·risc-v·1024程序员节
waves浪游2 小时前
库制作与原理(上)
linux·运维·服务器·开发语言·c++
wefg12 小时前
【Linux】进程地址空间的内核空间
linux·运维·服务器
不知名。。。。。。。。2 小时前
Linux网络基础
运维·服务器·网络
ZY小袁2 小时前
LVS(Linux virual server)实验
linux·运维·lvs
一直都在5722 小时前
SpringBoot+Vue+Netty+WebSocket+WebRTC 实现视频聊天
vue.js·spring boot·websocket
blockrock2 小时前
Linux Virtual Server (LVS)
linux·运维·lvs
蜡笔小炘2 小时前
Haproxy -- 高级功能配置及实用案例
linux·运维·服务器·haproxy
礼拜天没时间.2 小时前
Linux运维实战:巧用mv命令管理多版本Go环境,避免采坑
linux·运维·golang·centos