You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask SSE与Nginx配合运行异常问题求助

我之前在Flask+Gunicorn+Nginx的栈上跑SSE时踩过一模一样的坑!核心问题就是Nginx默认的缓冲、超时和连接配置会破坏SSE的长连接实时特性,结合你的场景给你一套完整的解决方案:

一、补全并修复Nginx配置

你的现有配置已经加了keepalive和proxy_buffering off,但还缺几个关键项,完整的配置应该是这样:

upstream backend {
    server 127.0.0.1:5000;
    keepalive 100;  # 维持与后端Gunicorn的长连接池,这个配置是对的
}

server {
    listen 80;
    access_log /var/log/nginx/client-access.log;
    error_log /var/log/nginx/client-error.log;

    location / {
        include proxy_params;
        proxy_pass http://backend;
        
        # 彻底关闭缓冲和缓存,避免SSE事件被积压
        proxy_buffering off;
        proxy_cache off;
        
        # 必须用HTTP/1.1才能支持长连接,HTTP/1.0不兼容
        proxy_http_version 1.1;
        # 强制设置连接为keep-alive,防止Nginx或后端主动断开
        proxy_set_header Connection "keep-alive";
        
        # 调整超时时间,避免Nginx因长时间无数据传输断开连接
        # 可以根据你的业务需求修改,比如设置为1小时
        proxy_connect_timeout 3600s;
        proxy_send_timeout 3600s;
        proxy_read_timeout 3600s;
        
        # 禁用压缩,压缩会把SSE的多个事件打包成块,前端无法实时解析
        proxy_set_header Accept-Encoding "";
    }

    # 如果你的SSE有单独的路径(比如/sse),建议单独配置这个location更精准
    location /sse {
        include proxy_params;
        proxy_pass http://backend;
        
        proxy_buffering off;
        proxy_cache off;
        proxy_http_version 1.1;
        proxy_set_header Connection "keep-alive";
        proxy_connect_timeout 3600s;
        proxy_send_timeout 3600s;
        proxy_read_timeout 3600s;
        proxy_set_header Accept-Encoding "";
    }
}

每个配置的作用简单说下:

  • proxy_http_version 1.1:SSE依赖HTTP长连接,只有1.1版本支持
  • proxy_set_header Connection "keep-alive":确保从前端→Nginx→Gunicorn整个链路都维持长连接
  • proxy_buffering off:Nginx默认会把后端响应缓冲完再发给前端,这直接让SSE的实时性报废,必须关
  • proxy_read_timeout:设置足够长的超时,不然Nginx会因为几分钟没数据就主动断开连接
  • Accept-Encoding "":禁用压缩,压缩会打乱SSE的逐帧传输格式
二、Gunicorn必须用异步Worker

Gunicorn默认的同步Worker会被SSE的长连接占满,导致其他请求无法处理,一定要用异步Worker,比如gevent:

  1. 先安装gevent:pip install gevent
  2. 启动Gunicorn时指定Worker类型:
gunicorn --worker-class=gevent --workers=4 --bind=127.0.0.1:5000 your_flask_app:app
  1. 记得在你的Flask入口文件开头加上猴子补丁,不然gevent无法正确处理IO:
from gevent import monkey
monkey.patch_all()
三、Flask-SSE的小检查

一般flask-sse会自动处理响应头,但可以手动确认你的SSE端点返回的头是否正确:

  • Content-Type必须是text/event-stream
  • Cache-Control设置为no-cache
  • Connection设置为keep-alive

如果是自定义SSE端点,代码可以这么写:

from flask import Response
import time

@app.route('/custom-sse')
def custom_sse():
    def event_generator():
        while True:
            # 生成符合SSE格式的事件(注意结尾的两个换行)
            yield 'data: 新消息来了!\n\n'
            time.sleep(5)
    return Response(
        event_generator(),
        mimetype='text/event-stream',
        headers={
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive'
        }
    )

最后记得重启Nginx和Gunicorn,然后用浏览器开发者工具的Network面板看SSE请求:状态码200,响应会持续保持打开状态,每有事件就会有数据块传输。

内容的提问来源于stack exchange,提问作者Vitor Villar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:16:32