本文記錄了一些nginx做爲反向代理和文件服務器的配置技巧和解決方案,原文會持續更新html
有時對於圖片、視頻,瀏覽器會視能力,自動爲用戶顯示或播放。這主要是因爲Web服務器在返回文件自己數據的同時,返回了一些特殊的MIME類型,好比:image/jpeg
(JPEG圖像),application/pdf
(PDF文檔),video/mpeg
(MPEG動畫)。這些MIMIE類型其實是告訴瀏覽器,文件數據究竟是什麼,這樣瀏覽器就能更好的爲用戶展現數據。如今像圖片、pdf、甚至是視頻基本都是能夠直接在瀏覽器中展現和播放的。可是有時,咱們須要瀏覽器爲用戶下載文件而不是直接播放,而Nginx在默認配置下,會根據文件的後綴來匹配相應的MIME類型,並寫入Response header,致使瀏覽器播放文件而不是下載,這時須要經過配置讓Nginx返回的MIME類型爲下面這個類型:前端
application/octet-stream
這個類型會讓瀏覽器認爲響應是普通的文件流,並提示用戶下載文件。能夠經過在Nginx的配置文件中作以下配置達到這樣的目的:nginx
location /download/ { types { } default_type application/octet-stream; }
這樣當Url路徑中包含/download/
時,MIME類型會被重置爲application/octet-stream
。另外,nginx自帶的MIME類型映射表保存在conf/mime.types
中。web
有的時候後端的Web-Server提供文件上傳的服務,可是若是前端使用Nginx作反向代理時,會出現文件沒法上傳的問題,這多是因爲Ngxin默認對客戶端請求的body的限制。由於,默認狀況下Nginx對客戶端請求的大小限制是1m,而上傳的文件每每超過1m。能夠經過修改以下配置項,來放寬這個限制:數據庫
client_max_body_size 10m;
將這個值設置爲0,能夠取消這個限制。這個配置項能夠用在http
, server
, location
配置節中。詳見client_max_body_size編程
一般狀況下,爲了保證用戶上傳的文件在服務器的文件系統中不至於重名,通常會將文件名修改爲guid後保存,並在數據庫中保持guid與文件名的映射。此時,若是使用Nginx來提供對這些用戶文件的下載功能的話,文件下載到用戶瀏覽器,會以文件的guid名做爲文件名,這顯然是用戶不想看到的。能夠考慮用這個方案。
假設咱們有一個文件的原始文件名爲test.txt
,對應的guid文件名是21EC2020-3AEA-1069-A2DD-08002B30309D.txt
,文件的虛擬路徑是/download/
後端
使用服務器端編程語言,在輸出的html中使用以下連接提供文件的下載:瀏覽器
<a href="/download/21EC2020-3AEA-1069-A2DD-08002B30309D.txt?n=test.txt" target='_blank'>下載test.txt</a>
能夠看到,將原始文件名以QueryString的方式帶在請求中,這樣能夠在Nginx端,利用$arg_name
變量來取到這個QueryString的值,從而重寫response header:服務器
add_header Content-Disposition "attachment; filename=$arg_n";
這會在response header中加入以下鍵值:app
Content-Disposition: "attachment; filename=test.txt";
經測試,不管是IE仍是Chrome均可以支持這個header。
關於Content-Disposition,詳見這裏
關於Nginx的標準http模塊的嵌入變量,詳見這裏
若是隻有一個公網IP,可是網站功能須要劃分爲多個不一樣的子網站或者子域名,能夠用Nginx來搭建反向代理來「複用」IP資源。假設有以下幾個域名都是abc.com這個主域的:
www.abc.com image.abc.com video.abc.com
1. 首先在DNS出注冊這3個域名同時指向同一個IP,Nginx做爲前端的web服務器,讓全部訪問這個IP地址80端口的請求所有指向Nginx
2. 而後,配置Nginx,根據域名將請求轉發轉發給內網的上游服務器,例以下面的配置:
server { listen 80; server_name www.abc.com; location / { proxy_pass http://192.168.1.100; } } server { listen 80; server_name image.abc.com; location / { alias /var/www/image; } } server { listen 80; server_name video.abc.com; location / { proxy_pass http://192.168.1.100:8081/video; } }
在上述配置中,將三個域名分發給了不一樣的模塊處理:
www.abc.com
分發給上游的http://192.168.1.100服務器處理image.abc.com
則直接映射到了Nginx本機的一個目錄video.abc.com
分發給上游的http://192.168.1.100:8081/video服務器處理(video是上游web-server的某虛擬目錄)Nginx做爲反向代理的時候,若是上游服務器處理時間過長的話,有時會返回504網關超時,從nginx的錯誤日誌看出若是是upstream timed out,就表示是上游服務器處理時間過長,Nginx認爲服務超時。Nginx在請求上游服務器時默認的超時時間爲1分鐘,能夠經過調整proxy_read_timeout
屬性增長這個超時時間
proxy_read_timeout 180s;