利用Nginx第三方模塊,實現網站中的打包下載

附件的打包下載,需要將一批邏輯上一起的文件,讓用戶通過一個下載按鈕打包下載。首先想到的方案是服務端調用什麼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,支持斷點續傳

基本使用

安裝

下載源碼:

重新編譯Nginx,不要make install:

將生成的二進制文件覆蓋現有的二進制文件。通常編譯出來的二進制文件位於源碼目錄的objs/nginx。更多關於如何添加第三方模塊看如何安裝nginx第三方模塊

使用方法

該模塊不需要在nginx.conf中配置任何東西,一切的行爲取決於上游服務器的響應內容。mod_zip規定當響應頭中包含X-Archive-Files的時候,將啓用mod_zip的功能:

同時,響應的body中需要包含一個欲打包的文件的列表,如:

每一行表示一個文件描述,行與行之間有一個換行符(最後也有個換行)。每行從左向右以空格分隔,依次是文件的crc-32校驗,文件大小(Byte),文件的uri,文件名。其中crc-32可以忽略,並用-代替,文件名可以包含目錄,會體現在最後的壓縮包中的目錄結構中。

重點是文件的uri怎麼理解。這裏的/foo.txt/bar.txt並非指向文件系統的路徑,而是一個子請求的地址。比如上面的/foo.txt實際上會產生一個Nginx自身的請求:http://host/foo.txt,至於這個請求得到什麼又要根據nginx.conf中的配置決定了。這樣的設計十分靈活,例如下面的配置:

於是,可以這樣使用文件uri:

這樣兩個文件分別會向遠程服務器請求文件:

上游服務器可以通過在頭部注入Content-Disposition來控制zip文件的輸出文件名

上游服務器示例

下面是個測試用的上游服務器例子

發佈了55 篇原創文章 · 獲贊 19 · 訪問量 43萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章