nginx反向代理下載文件失敗處理

最近遇到了客戶在從咱們的服務器下載文件失敗時的狀況。而後把解決方案一併整理一下以備後續。須要說明的是,咱們前端都是使用nginx來作反向代理,後面的邏輯處理採用php的方式。php

一、緩存目錄不可寫前端

nginx在作反向代理,代理後端的nginx+php-fpm時,在客戶端下載文件時,老是下載到必定的大小,就下載不動,查看後端服務器,表現正常,在繞過前端反向代理,直接從後端下載,也正常。檢查反向代理服務器日誌,拋出以下異常:nginx

2017/01/16 11:54:38 [warn] 3748#0: *61038342 an upstream response is buffered to a temporary file /usr/local/tengine/proxy_temp/5/03/0000000035 while reading upstream, client: 192.168.42.190, server: preview-qa.fdccloud.com, request: "GET /zip/033ca15a28b33298b46bc1e7eb2ea0f24cde16f9/%E9%99%84%E4%BB%B6%E9%97%AE%E9%A2%98/04%E6%98%8E%E6%BA%90%E7%A7%BB%E5%8A%A8V3.0%E4%BA%A7%E5%93%81%E5%8F%91%E5%B8%83%E5%85%AC%E5%91%8A-%E7%A7%BB%E5%8A%A8%E8%AE%A1%E5%88%92.pptx HTTP/1.1", upstream: "http://127.0.0.1:2016/zip/033ca15a28b33298b46bc1e7eb2ea0f24cde16f9/%E9%99%84%E4%BB%B6%E9%97%AE%E9%A2%98/04%E6%98%8E%E6%BA%90%E7%A7%BB%E5%8A%A8V3.0%E4%BA%A7%E5%93%81%E5%8F%91%E5%B8%83%E5%85%AC%E5%91%8A-%E7%A7%BB%E5%8A%A8%E8%AE%A1%E5%88%92.pptx", host: "preview-qa.fdccloud.com"
是由於/usr/local/tengine/proxy_temp目錄沒有權限,修改文件權限爲nginx進程用戶之後,即正常。
緣由分析:
nginx代理nginx時,前端用戶請求下載文件, nginx代理會先從後端nginx拿到文件並緩存到本地,而後響應給客戶端,其中與proxy buffer相關的配置項以下:
proxy_buffer_size 512k;
proxy_buffers 4 512k;
proxy_busy_buffers_size 512k;
proxy_temp_file_write_size 512k;
由此可知, buffer緩衝區最大能夠緩衝2.5M的數據,而後就開始刷寫磁盤,若是磁盤沒法寫入,數據丟失。這也是爲何前端下載部分數據,即下載不動的緣由。
 
二、下載大文件超時
 
客戶端在下載大文件時,下載到1G時就會顯示「下載失敗」,FireFox中若是繼續下載,則還會再下載1G,而後再失敗。反向代理的錯誤日誌以下:
2016/11/25 11:23:47 [error] 67663#0: *11 upstream prematurely closed connection while reading upstream, client: ...

被代理服務器的錯誤日誌:後端

2016/11/24 23:33:02 [error] 5833#101125: *8559 upstream timed out (60: Operation timed out) while reading response header from upstream, client: ....
緣由分析:
 1)、代理服務器報告:上游過早的關閉鏈接,好像問題出在被代理服務器;而被代理服務器則抱怨:上游服務器超時。那麼一個很合理的推論是:代理服務器很長時間沒向被代理服務器請求數據,被代理服務器認爲代理服務器已經掉線或完成任務,因而主動斷開鏈接,代理服務器發現須要數據,再鏈接時,已經鏈接不上了。
 2)、正常的流程應該是:只要客戶端一直下載,「客戶機->代理服務器->被代理服務器」,這一連串的數據流不會中斷,也就不會出現超時。
 3)、出現超時只能有一種狀況:代理服務器緩存了大文件。
 4)、代理服務器接到下載請求,向被代理服務器請求數據,因爲兩個服務器之間網速快,因此代理服務器請求速度要遠大於向客戶端發送的速度,這就致使一下正常的代理方式:代理服務器要緩存數據。
 5)、可是兩個服務器之間的速度實在是太快了,緩存1G數據也就是分分鐘的事情,而客戶端須要慢慢下載,可能須要十幾、甚至幾十分鐘。代理服務器和被代理服務器這段時間內沒有什麼事可幹,與是兩端靜默的時間一長,超過了timeout的時間(通常是60s),被代理服務器就認爲代理服務器掉線。
 
解決方案:
1)將代理服務器緩存設置更大,能夠直接緩存整個文件,跟上面的解決同樣
2)禁用代理服務器緩存:
proxy_pass http://192.168.0.1;
proxy_redirect default;
proxy_buffering off;
3)設置更長的超時時間
proxy_send_timeout 90; #後端服務器數據回傳時間(代理髮送超時)
proxy_read_timeout 90; #鏈接成功後,後端服務器響應時間(代理接收超時)
相關文章
相關標籤/搜索