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

Django+Nginx+uWSGI环境下文件下载配置设置及代码故障解决

嘿,咱们来排查下你的Django+Nginx+uWSGI文件下载总是失败的问题。我会从代码优化和服务配置调整两方面给你解决方案:

一、先修复代码里的潜在问题

你的现有代码有几个小问题可能导致下载异常:

  1. 文件句柄泄漏:直接用open()没有关闭文件,长期运行会耗尽系统资源
  2. 冗余的FileWrapper:Django的FileResponse已经内置了流式传输支持,不需要手动包装FileWrapper
  3. 不标准的404响应:返回Response(status=404)不如用Django标准的HttpResponseNotFound更规范

优化后的代码:

import os
from django.http import FileResponse, HttpResponseNotFound
from .models import DB

def download_latest_db(request):
    latest_db = DB.objects.all().first()
    chunk_size = 8192  # 这个大小没问题,保持即可
    if latest_db is not None:
        # 用with语句自动管理文件句柄,避免泄漏
        with open(latest_db.locate, 'rb') as db_file:
            response = FileResponse(db_file, chunk_size=chunk_size)
            response['Content-Length'] = os.path.getsize(latest_db.locate)
            response['Content-Disposition'] = f'attachment; filename="{latest_db.version}.db"'
            return response
    # 返回标准404响应
    return HttpResponseNotFound("No available database file to download")

二、调整uWSGI配置

大文件下载时,uWSGI的默认超时和缓冲区设置可能不够,导致连接中断。修改你的uWSGI配置文件(比如uwsgi.ini),添加以下参数:

# 增大响应缓冲区,防止大文件传输时缓冲区溢出
output-buffer = 32768
# 设置请求超时时间(单位:秒),根据你的文件大小调整,比如设为5分钟(300秒)
harakiri-timeout = 300
# 套接字超时时间,和harakiri保持一致
socket-timeout = 300
# 如果你用HTTP协议连接Nginx而非Unix套接字,添加这个
http-timeout = 300
# 开启线程支持(确保Django能处理流式传输的并发)
enable-threads = true

三、修改Nginx配置

Nginx作为反向代理,默认的代理缓冲区和超时设置也会截断大文件下载。在你的Nginx站点配置的server块里,针对下载接口的location添加以下配置:

location /download/latest-db/ {  # 替换成你实际的下载接口路径
    proxy_pass http://uwsgi_backend;  # 替换成你的uWSGI后端地址,比如unix:/var/run/uwsgi/your_project.sock 或者 http://127.0.0.1:8000
    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_buffering off;
    # 基础缓冲区配置(如果开启缓冲的话,不过大文件建议关闭)
    proxy_buffer_size 32k;
    proxy_buffers 8 32k;
    proxy_busy_buffers_size 64k;

    # 设置代理超时时间,和uWSGI保持一致
    proxy_connect_timeout 300s;
    proxy_send_timeout 300s;
    proxy_read_timeout 300s;

    # 确保下载相关的响应头能正确传递给客户端
    proxy_pass_header Content-Disposition;
    proxy_pass_header Content-Length;
}

四、必查的权限问题

别忘了检查uWSGI运行用户对数据库文件的读取权限!如果uWSGI的运行用户(比如www-data)没有权限读取latest_db.locate指向的文件,下载会静默失败。你可以:

  • 给文件添加全局读权限:chmod o+r /path/to/your/db/file.db
  • 或者把uWSGI用户加入文件所在的用户组:usermod -aG your_file_group www-data

最后一步:重启服务

修改完配置后,依次重启uWSGI和Nginx:

# 重启uWSGI(根据你的启动方式调整)
systemctl restart uwsgi
# 重启Nginx
systemctl restart nginx

这样调整后,应该就能解决大部分下载失败的问题了。如果还是有问题,可以查看uWSGI和Nginx的日志(比如/var/log/uwsgi/和/var/log/nginx/目录下的日志),看看有没有具体的错误提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:37:55