IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Nginx的X-Accel-Redirect实现大文件下载 -> 正文阅读

[系统运维]Nginx的X-Accel-Redirect实现大文件下载

一、文件下载的几种方式

1、直接给出下载地址,使用静态文件服务器nginx下载。任何人都可以下载,无法控制用户的权限。
2、后端流式读取文件内容,设置header后疯狂输出
django文档中提到,可以向HttpResponse传递一个迭代器,流式的向客户端传递数据,如下:
def read_file(filename, buf_size=8192):
??? with open(filename, "rb") as f:
??????? while True:
??????????? content = f.read(buf_size)
??????????? if content:
??????????????? yield content
??????????? else:
??????????????? break

def big_file_download(request):
??? //可做过滤、权限控制等操作
?? ?filename = "filename"
??? response = HttpResponse(read_file(filename))
??? response['content_type'] = 'application/octet-stream' # 设置头信息,告诉浏览器这是个文件
??? response['Content-Disposition'] = 'attachment; filename=%s' % filename
??? return response

这样做可以实现权限的控制,但这个过程需要后端进程将文件读取到内存中然后再发给用户,会造成很大的资源开销。如果你文件较大,可能会超时,并且会占用比较大的内存,当用户下载量很大时有可能造成程序的崩溃

3、后端过滤与权限控制,再发出指令给web服务器来传输静态文件
Django(做权限判断)+nginx(配合X-Accel-Redirect机制下载文件)
优点:传输快、服务器IO低
缺点:需要nginx配置权限,另外后端无法知道传完了没有,没有后续操作空间

二、什么是 X-Sendfile?

X-Sendfile是一种将文件下载请求由后端应用转交给前端web服务器处理的机制,它可以消除后端程序既要读文件又要处理发送的压力,从而显著提高服务器效率,特别是处理大文件下载的情形下
X-Sendfile 通过一个特定的 header 来实现:在 X-Sendfile 头中指定一个文件的地址来通告前端 web 服务器。当 web 服务器检测到后端发送的这个 header 后,它将忽略后端的其他输出,而使用自身的组件(包括 缓存头 和 断点重连 等优化)机制将文件发送给用户。
不过,在使用 X-Sendfile 之前,我们必须明白这并不是一个标准特性,在默认情况下它是被大多数 web 服务器禁用的。而不同的 web 服务器的实现也不一样,包括规定了不同的 X-Sendfile 头格式。如果配置失当,用户可能下载到 0 字节的文件。
使用X-Sendfile的缺点是你失去对文件传输机制的控制,后台不知道文件是否下载成功

三、X-Sendfile在nginx中的应用

Nginx 默认支持该特性 ,不需要加载额外的模块。只是实现有些不同, 需要发送的 HTTP 头为 X-Accel-Redirect。
X-Accel-Redirect:
这个功能允许你在后端处理权限,日志或任何你想干的,Nginx提供内容服务给终端用户从重定向后的路径,因此可以释放后端去处理其他请求(直接由Nginx提供IO,而不是后端服务)。这个功能类似 X-Sendfile 。
需要在nginx配置:
# Will serve /var/www/protected_files/myfile.tar.gz
# When passed URI /protected_files/myfile.tar.gz
location /protected_files {
??? internal;? ?? #?internal 表示这个路径只能在 Nginx 内部访问,不能用浏览器直接访问防止未授权的下载
??? root /var/www;
}
当向django view函数发起request时,django负责对用户权限进行判断或者做些其它事情,然后向nginx转发url为/protected_files/filename的请求,nginx服务器负责文件/var/www/protected_files/filename的下载
response['X-Accel-Redirect']='/protected_files/%s' % filename

四、案例?

Django(做权限判断)+nginx(配合X-Accel-Redirect机制下载文件) 代码实现:
  1. 文件07a949d969cea243f8755f72d741ae69729e2fa1.img存放在/var/www/html/download/目录下
  2. Nginx监听8099端口。
  3. Nginx代理后端服务的8000端口。
  4. 设置/download路径为internal,指定具体文件存储的磁盘位置。
  5. 后端服务接收到文件下载请求,处理业务逻辑后X-Accel-Redirect到/download路径
  6. Nginx收到后端返回信息中的X-Accel-Redirect请求头,接管文件下载或显示任务
Nginx配置:
?
server {
??? listen? 8099;
??? server_name? 192.168.11.135;
??? location /download {
??????? internal;??#?internal 表示这个路径只能在 Nginx 内部访问,不能用浏览器直接访问防止未授权的下载
????????root? /var/www/html;?
??? }
????
??? location / {
??????? client_max_body_size 2048M;
??????? proxy_pass http://192.168.11.135:8000;
??????? proxy_set_header Host $host:$server_port;
??????? proxy_set_header??????? X-Real-IP $remote_addr;
??????? proxy_set_header??????? X-Forwarded-For $proxy_add_x_forwarded_for;
??????? proxy_set_header??????? X-Forwarded-Proto $scheme;
??? }
}
python代码:
@require_GET
def download(request):
??? filename = request.GET.get("filename")
??? # 统计
??? # 鉴权
??? # 判断Referer

??? # 通过X-Accel-Redirect返回在nginx中的实际下载地址
??? response = HttpResponse()
??? response['X-Accel-Redirect'] = '/download/%s' % filename
??? response['Content_Type'] = 'application/octet-stream'
??? response["Content-Disposition"] = "attachment; filename={0}".format(filename)

??? # response["X-Accel-Limit-Rate"] = "1024"? # 限速,单位字节,默认不限
??? # response["X-Accel-Buffering"] = "yes"? # 是否使用Nginx缓存,默认yes
??? return response
如果直接访问路径:http://192.168.11.135:8099/download/07a949d969cea243f8755f72d741ae69729e2fa1.img,就会报404错误,因为internal;
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-11-05 00:57:57  更:2022-11-05 01:00:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 19:30:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码