Django+Nginx+uWSGI环境下文件下载配置设置及代码故障解决
嘿,咱们来排查下你的Django+Nginx+uWSGI文件下载总是失败的问题。我会从代码优化和服务配置调整两方面给你解决方案:
一、先修复代码里的潜在问题
你的现有代码有几个小问题可能导致下载异常:
- 文件句柄泄漏:直接用
open()没有关闭文件,长期运行会耗尽系统资源 - 冗余的FileWrapper:Django的
FileResponse已经内置了流式传输支持,不需要手动包装FileWrapper - 不标准的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
相关产品推荐
相关产品推荐

