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; #链接成功后,后端服务器响应时间(代理接收超时)
相关文章
相关标签/搜索