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

Flask+Gunicorn+Nginx大文件上传超时连接重置问题求助

大文件上传进度冻结及连接重置问题解决

问题背景

搭建基于Flask、Gunicorn、Nginx的个人服务器,实现带进度显示的文件上传功能,但上传大文件(耗时超30秒)时,进度会在30秒时冻结,约1分钟后恢复,5秒后再次冻结,最终3.5分钟左右出现net::ERR_CONNECTION_RESET错误。

已尝试无效方案

  • 使用Gunicorn的gevent worker,并在启用/禁用该worker时测试
  • Gunicorn启动参数添加--log-level debug --keep-alive 30 --timeout 300 --graceful-timeout 300,无变化且调试日志无上传相关信息
  • Nginx的http段添加proxy_connect_timeout 300s;、proxy_read_timeout 300s;和client_max_body_size 100G;

有效解决步骤

1. 完善Nginx代理配置

Nginx的http段配置可能未覆盖到具体代理location,需在代理到Gunicorn的location块中补充以下配置,确保上传过程的超时控制和实时进度传递:

location / {
    # 保留原有代理配置(如proxy_pass http://127.0.0.1:8000;)
    client_body_timeout 300s;       # 客户端请求体传输超时
    proxy_send_timeout 300s;        # Nginx向Gunicorn发送请求超时
    proxy_read_timeout 300s;        # Nginx等待Gunicorn响应超时
    proxy_connect_timeout 300s;     # Nginx与Gunicorn建立连接超时
    proxy_buffering off;            # 禁用代理缓冲,让进度事件实时传递到前端
    chunked_transfer_encoding on;   # 启用分块传输,适配大文件上传场景
}

2. 调整Gunicorn与Flask配置

  • 若使用gevent worker,确保已安装gevent,启动参数调整为:
    gunicorn -w 4 -k gevent --timeout 300 --graceful-timeout 300 --keep-alive 300 --log-level debug app:app
    
    (-w 4根据服务器CPU核心数调整,--keep-alive设为300避免连接过早断开)
  • 在Flask应用中添加大文件限制配置,避免Flask层面截断请求:
    app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 * 1024 * 1024  # 100G,与Nginx配置保持一致
    

3. 优化Flask上传处理逻辑

默认的file.save()会一次性将大文件读取到内存,导致Gunicorn worker长时间阻塞,引发超时。改为分块读取保存,释放worker资源:

# 替换原views.py中的file.save(...)代码
file_path = os.path.join(BASE_DIR + path, secured_filename)
chunk_size = 1024 * 1024  # 按1MB分块读取
with open(file_path, 'wb') as f:
    while chunk := file.stream.read(chunk_size):
        f.write(chunk)

4. 检查服务器系统级超时设置

  • 检查Linux系统TCP连接超时参数,若默认值过小,可临时调整:
    echo 300 > /proc/sys/net/ipv4/tcp_keepalive_time
    echo 60 > /proc/sys/net/ipv4/tcp_keepalive_intvl
    echo 5 > /proc/sys/net/ipv4/tcp_keepalive_probes
    
  • 检查云服务器安全组或防火墙是否有连接超时限制,确保TCP连接超时设置≥300秒。

5. 前端错误监听优化

添加错误和超时监听,便于后续排查问题:

function uploadFile(path) {
    let formdata = new FormData();
    let req = new XMLHttpRequest();
    let filesize = document.getElementById("fileInput").files[0].size;

    formdata.append("fileinput", document.getElementById("fileInput").files[0]);

    req.upload.addEventListener('progress', (uploadEvent) => {
        let progressElem = document.getElementById('progressIndicator');
        if (uploadEvent.loaded < filesize) {
            progressElem.innerHTML = (100 * uploadEvent.loaded / filesize).toFixed(2) + '%';
        } else {
            progressElem.style.color = "green";
            progressElem.innerHTML = "✅ 文件上传完成";
        }
    });

    // 上传错误监听
    req.addEventListener('error', (e) => {
        console.error('上传错误详情:', e);
        const progressElem = document.getElementById('progressIndicator');
        progressElem.style.color = "red";
        progressElem.innerHTML = "❌ 上传失败: 连接重置";
    });

    // 上传超时监听
    req.addEventListener('timeout', () => {
        const progressElem = document.getElementById('progressIndicator');
        progressElem.style.color = "red";
        progressElem.innerHTML = "❌ 上传超时";
    });

    req.open("POST", path);
    req.timeout = 300000; // 设置请求超时为5分钟
    req.send(formdata);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 04:15:39