资讯专栏INFORMATION COLUMN

利用Nginx第三方模块,实现附件打包下载

Cruise_Chan / 2658人阅读

摘要:前一阵子被一个需求困扰附件的打包下载,需要将一批逻辑上一起的文件,让用户通过一个下载按钮打包下载。用户体验也是问题,因为必须打包完成后,才能开始返回,无法边打包边下载。

  

前一阵子被一个需求困扰:附件的打包下载,需要将一批逻辑上一起的文件,让用户通过一个下载按钮打包下载。首先想到的方案是服务端调用什么zip之类的类库,将文件打包好后返回客户端。但是这样做有一个很明显的问题:文件很多很大的情况下,打包可能会占用大量的内存和cpu,就算在磁盘上构建临时的打包文件,也会增加服务器的磁盘IO负担,而且这些临时的文件无故占用大量的磁盘空间,删除还是个问题。用户体验也是问题,因为必须打包完成后,才能开始返回,无法边打包边下载。本来都准备放弃了,不过发现百度网盘好像实现了这个功能,于是再次考虑如何实现。想到我们实际上使用了Nginx作为文件服务器,会不会有第三方模块能够支持这种功能呢?寻觅之后果然有结果,就是本文要探讨的mod_zip。

mod_zip介绍

mod_zip能够动态的构建zip包,这种动态体现在当Nginx作为反向代理服务器的时候,该模块能够根据上游服务器返回的文件列表来打包文件。mod_zip实际上是利用Nginx的subrequest功能,将zip流发送到客户端的,而且它实际上只打包不压缩,所以借助Nginx本身作为文件服务器的能力,该模块的内存占用十分少,对于上G的大文件也没有问题。zip文件本身是结构化的,可以自定义目录结构,所以对于mod_zip而言,要做的只是添加zip的头部尾部和zip内部的目录结构元数据而已,文件数据本身依靠Nginx自身的机制发送。

除此之外,还有如下两点:

由于使用subrequest机制,文件甚至可以不在Nginx的服务器本身,可以是上游服务器,甚至是互联网的远程服务器上

在添加crc校验后,mod_zip还能够支持HTTP的Range,支持断点续传

基本使用 安装

下载源码:

$ git clone https://github.com/evanmiller/mod_zip.git

重新编译Nginx,不要make install:

$ ./configure --add-module=/src/mod_zip
$ make

将生成的二进制文件覆盖现有的二进制文件。通常编译出来的二进制文件位于源码目录的objs/nginx。更多关于如何添加第三方模块看如何安装nginx第三方模块

使用方法

该模块不需要在nginx.conf中配置任何东西,一切的行为取决于上游服务器的响应内容。mod_zip规定当响应头中包含X-Archive-Files的时候,将启用mod_zip的功能:

X-Archive-Files: zip

同时,响应的body中需要包含一个欲打包的文件的列表,如:

1034ab38 428    /foo.txt   My Document1.txt
83e8110b 100339 /bar.txt   My Other Document1.txt

每一行表示一个文件描述,行与行之间有一个换行符(最后也有个换行)。每行从左向右以空格分隔,依次是文件的crc-32校验,文件大小(Byte),文件的uri,文件名。其中crc-32可以忽略,并用-代替,文件名可以包含目录,会体现在最后的压缩包中的目录结构中。

重点是文件的uri怎么理解。这里的/foo.txt/bar.txt并非指向文件系统的路径,而是一个子请求的地址。比如上面的/foo.txt实际上会产生一个Nginx自身的请求:http://host/foo.txt,至于这个请求得到什么又要根据nginx.conf中的配置决定了。这样的设计十分灵活,例如下面的配置:

location ~ "^/(?server[12])/(?.*txt)" {
    proxy_pass http://$srv.domain.com/$file
}

于是,可以这样使用文件uri:

1034ab38 428    /server1/foo.txt   My Document1.txt
83e8110b 100339 /server2/bar.txt   My Other Document1.txt

这样两个文件分别会向远程服务器请求文件:

http://server1.domain.com/foo.txt
http://server2.domain.com/bar.txt

上游服务器可以通过在头部注入Content-Disposition来控制zip文件的输出文件名

Content-Disposition: attachment; filename=foobar.zip
上游服务器示例

下面是个测试用的上游服务器例子


文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/39072.html

相关文章

  • 利用Nginx三方模块实现附件打包下载

    摘要:原文利用第三方模块,实现附件打包下载前一阵子被一个需求困扰附件的打包下载,需要将一批逻辑上一起的文件,让用户通过一个下载按钮打包下载。用户体验也是问题,因为必须打包完成后,才能开始返回,无法边打包边下载。 原文:利用Nginx第三方模块,实现附件打包下载 前一阵子被一个需求困扰:附件的打包下载,需要将一批逻辑上一起的文件,让用户通过一个下载按钮打包下载。首先想到的方案是服务端调用什么...

    Batkid 评论0 收藏0
  • 服务器端文件分片合并的思考和实践

    摘要:原文服务器端文件分片合并的思考和实践笔者在项目中处理大文件上传的需求,仿照七牛云存储的接口设计。然而,在服务器端文件合并时遇到了很大的问题合并太慢。服务器端的分片合并现在进入本文的重点。 原文:服务器端文件分片合并的思考和实践 笔者在项目中处理大文件上传的需求,仿照七牛云存储的接口设计。然而,在服务器端文件合并时遇到了很大的问题:合并太慢。本文记录了当时的思路和解决的方案 大文件的...

    huaixiaoz 评论0 收藏0
  • Linux定时备份数据库到指定邮箱

    摘要:本文转自豆浆下每天备份数据库并发送到指定邮箱一配置邮箱这里使用的是网易邮箱邮箱的服务,服务器是。成功收到邮件,没问题。编写脚本和定时任务万事俱备,接下来要做自动化工作建立一个备份脚本,并使用定时任务每天执行它。 本文转自豆浆Melon :linux下每天备份Mysql数据库并发送到指定邮箱 一、配置邮箱 这里使用的是网易邮箱126邮箱的STMP服务,服务器是smtp.126.com。如...

    Jacendfeng 评论0 收藏0
  • Linux定时备份数据库到指定邮箱

    摘要:本文转自豆浆下每天备份数据库并发送到指定邮箱一配置邮箱这里使用的是网易邮箱邮箱的服务,服务器是。成功收到邮件,没问题。编写脚本和定时任务万事俱备,接下来要做自动化工作建立一个备份脚本,并使用定时任务每天执行它。 本文转自豆浆Melon :linux下每天备份Mysql数据库并发送到指定邮箱 一、配置邮箱 这里使用的是网易邮箱126邮箱的STMP服务,服务器是smtp.126.com。...

    hellowoody 评论0 收藏0
  • VUE-Router按模块配置、懒加载+ Windows中Nginx服务安装、配置解决404

    摘要:文章涉及到路由模块化,懒加载,安装,打包配置板块。项目复杂,路由变多,代码维护性降低,从路由模块化开始一步步优化,解决各种。无法启动服务,报错参考资料发现端口冲突,已经在服务中已经配置端口。服务端口更改为。 文章涉及到VUE路由模块化,懒加载,nginx安装,打包配置板块。项目复杂,路由变多,代码维护性降低,从路由模块化开始一步步优化,解决各种BUG。参考了很多方法,会在文章中引用出来...

    habren 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<