Nginx反向代理導致大文件下載失敗
一、現象:
Nginx反向代理,被代理也是nginx,客戶端在下載大文件時,下載到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、禁用緩存,客戶端的每次清求都轉發到被代理服務器,做法是在代理服務器的ngnix配置裡面添加:proxy_redirect default ;
- proxy_pass http://192.168.0.1;
- proxy_redirect default ;
- proxy_buffering off;
2、加大兩個服務器之間的timeout,在被代理服務器的配置裡添加:
- client_body_timeout 3600;
- client_header_timeout 1800;
- keepalive_timeout 15;
- send_timeout 3600;
這幾個實際上是有很大差別的,如果區分不清,還是全部設置上吧。
--end--