springboot X-Accel-Redirect 大文件下载实现

news/2024/11/27 15:25:44/

文章目录

  • 前言
  • 一、什么是 X-Sendfile?
  • 二、相关请求头说明
  • 三、食用步骤
  • 总结


前言

文件下载的方式:

  1. nginx代理附件路径,直接访问。无法控制用户的权限。
  2. 服务端流式读取文件内容。这个过程需要后端进程将文件读取到内存中然后再发给用户,会造成很大的资源开销。如果你文件较大,可能会超时,并且会占用比较大的内存,当用户下载量很大时有可能造成程序的崩溃。
  3. 服务端权限控制后通过X-Accel-Redirect 重定向到nginx代理地址。传输快、服务器IO低,但是无法跟踪下载进度。

一、什么是 X-Sendfile?

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

nginx: X-Accel-Redirect

squid: X-Accelerator-Vary

apache: X-Sendfile

lighttpd: X-Sendfile/X-LIGHTTPD-send-file

使用X-Sendfile的缺点是你失去对文件传输机制的控制,后台不知道文件是否下载成功。

Nginx 默认支持该特性 ,不需要加载额外的模块。只是实现有些不同, 需要发送的 HTTP 头为 X-Accel-Redirect。

X-Accel-Redirect:
这个功能允许你在后端处理权限,日志或任何你想干的,Nginx提供内容服务给终端用户从重定向后的路径,因此可以释放后端去处理其他请求(直接由Nginx提供IO,而不是后端服务)。这个功能类似
X-Sendfile 。

二、相关请求头说明

X-Accel-Limit-Rate
限制下载速度,单位字节。默认不限速度。

X-Accel-Buffering
设置此连接的代理缓存,将此设置为no将允许适用于Comet和HTTP流式应用程序的无缓冲响应。将>此设置为yes将允许响应被缓存。默认yes。

X-Accel-Expires
如果已传输过的文件被缓存下载,设置Nginx文件缓存过期时间,单位秒。默认不过期。

X-Accel-Charset
设置文件字符集,默认UTF-8

三、食用步骤

前置条件:
需要前端请求的Referer 和 nginx 在同一台机器,或者nginx代理到最终附件服务器的nginx地址

  1. nginx代理附件地址和附件下载服务(保证代理和服务在同一个ip 端口下)
location /protected_files {internal;     # internal 表示这个路径只能在 Nginx 内部访问,不能用浏览器直接访问防止未授权的下载alias /mnt/files;
}location /gsdss-api/ {#OPTIONS请求处理if ($request_method = 'OPTIONS') {add_header 'Access-Control-Max-Age' 1728000;add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Credentials true;add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,token,orgcode';return 200;}proxy_pass 网关地址;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;client_max_body_size 100m;proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
}
  1. java处理鉴权后直接重定向到nginx代理地址
    public void downloadByLink(HttpServletResponse response, String fileId) {//查询附件信息AttachmentResp resp = attachmentService.findByAttachId(fileId);//鉴权实际已经通过gateway完成try {String fileName = URLEncoder.encode(resp.getFileName(), "UTF-8");response.addHeader("Content-Disposition", "attachment;filename=" + fileName);response.setHeader("X-Accel-Redirect", "/upload" + resp.getPath()); //设置URI给nginx进行内部的跳转response.setHeader("X-Accel-Limit-Rat", "202400"); //限速} catch (UnsupportedEncodingException e) {log.error("文件下载失败 ", e);throw new BusinessException("文件下载失败");}}

总结

常规请求路径
前端nginx:前端访问nginx代理网关路径
后端nginx:

  1. 代理网关路径转发到实际网关地址
  2. 网关分发到附件服务
  3. 附件服务处理请求

为了保证nginx代理的下载路径和附件下载服务在同一ip和端口那么这个nginx代理需要2层实现
比较乱 凑合看

在这里插入图片描述


http://www.ppmy.cn/news/163122.html

相关文章

HMDB 51

HMDB 51 内容: 1 共51个类别,6849个视频。每一个类别至少包含101个视频。 2 从电影、视频网站上采集。 3 包含5大类: 面部动作(微笑、大笑、咀嚼、说话); 面部与物交互动作(吃饭、喝水、…

.md文件是什么?.md如何打开?

可能有些朋友会看到以md为结尾的文件,但是不知道用什么打开。下面就来说一下.md文件如何打开,markdown文件用什么打开。 1、首先来普及一下什么是md文件, md全称markdown,markdown也是一种标记语言。   2、md文件其实可以用常用…

md文件的打开

可能有些朋友会看到以md为结尾的文件,但是不知道用什么打开。推荐大家用typora。 下载 下载(免费版): https://www.123pan.com/s/c8zA-wkzN3 官方网站: 添加链接描述 Markdown教程: 添加链接描述 打开md文件效果:

md文件的正确打开方式

常常会遇到md格式的文件,默认打开方式是记事本,但是打开后不利于阅读,体验很差。 直到今天才明白,正确打开md文件是一件多么美妙的事情!!! 可以使用**Notepad**来打开,该软件在编程方…

MD290,MD380,MD500变频器源码

汇川三种变频器源码,MD290,MD380,MD500变频器源码,基于TMS320F28035。 新的SVC3算法,高速速度波动小,新的转子电阻,漏感辩识算法! 链接:https://pan.baidu.com/s/1sXD-QgRP2rLtGE6vn7geyw?pwd1sl3 提取码…

MD04, MD05, MD07, MD07区别

md07和md04是库存/需求清单的集中读取和单独读取; md06和md05是MRP清单的集中读取和单独读取; 这两组事务码的主要区别是:一个是动态的,一个是静态的; 库存/需求清单在运行完Mrp后,还会根据库存和需求的…

%md ,%0md ,%-md ,%m.nf

%d:正常输出 %md:   d 表示输出的数据是整数   m 表示输出数据的宽度,右对齐,若数据实际位数小于m时左边补空   格,若大于m,则按实际位数输出 %0md:若实际位数小于m时,左边补0&#xff…

LT9721 MIPI DSI/HDMI转TYPE-C

龙迅LontiumLT9721是MIPI/HDMI到DP转换器,带有内部Type-C交替模式开关和PD控制器。 对于MIPIDSI输入,LT9721具有单端口MIPIDSI接收器,具有1个时钟通道和4个数据通道,每个数据通道最大1.5Gbps,最大输入带宽为6Gbps。转换…