图片显示过慢,文件下载不完全,竟然是Nginx的锅
写在前面
最近,一名读者跟我说他通过浏览器访问自己的服务器时,图片显示的非常慢,以至于在浏览器中都无法完全加载出来,下载文件时,更是恼火,文件根本就无法完全下载下来。而且奇怪的是这位读者所在的网络是没啥问题的。于是,我便开始帮他排查各种问题。。。
问题定位
经过一系列的排查(中间过程我就省略了,直接写重点了!),最终定位到是Nginx的问题。当我打开这位读者的网站后台管理系统,发现图片显示非常慢,在Nginx前端代理上查出如下错误信息。
[error]?28423#0:?*5?connect()?failed?(111:?Connection?refused)?while?connecting?to?upstream
直接在后台服务器上用后台服务器的IP地址去访问,发现速度相当快,于是怀疑是Nginx的配置问题。
注意:当下载大的附件,或是页面中有大图片时,就会下载中断或是图片无法显示,也许你会说我用的Nginx缺省的配置也从来没有碰到过这种问题呀!我想说的是:那是因为你的网站没有大文件,至少没有大到使用Nginx的默认配置加载不出来。
这里,我给出一段Nginx的配置,如下所示。
location?/file?{
?????root?/home/file;
?????index??index.html?index.htm;
?????proxy_set_header?X-Real-IP?$remote_addr;
?????proxy_set_header???Host?$host;
?????proxy_pass?http://127.0.0.1:8080?;
?????client_max_body_size?????100m;
?????client_body_buffer_size??128k;
?????proxy_connect_timeout????600;
?????proxy_read_timeout???????600;
?????proxy_send_timeout???????600;
?????proxy_buffer_size????????32k;
?????proxy_buffers??????????4?64k;
?????proxy_busy_buffers_size?64k;
?????proxy_temp_file_write_size?64k;
}
其中几个重要的参数如下所示。
- proxy_connect_timeout 600; #nginx跟后端服务器连接超时时间(代理连接超时)
- proxy_read_timeout 600; #连接成功后,后端服务器响应时间(代理接收超时)
- proxy_send_timeout 600; #后端服务器数据回传时间(代理发送超时)
- proxy_buffer_size 32k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
- proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
- proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
- proxy_temp_file_write_size 16k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传
看到这里,发现问题了,这位读者的Nginx有下面一行配置。
proxy_temp_file_write_size?16k;
而他服务器上的图片基本都在100K~5M之间。
问题就出在proxy_temp_file_write_size上,当服务器上的文件超过该参数设置的大小时,Nginx会先将文件写入临时目录(缺省为Nginx安装目下/proxy_temp目录),缺省Nginx是以nobody身份启动的,用ls -al 命令查看proxy_temp目录 nobody是proxy_temp目录的所有者,怪了那为什么没权限呢?接下来查看proxy_temp的父目录既Nginx安装目录。发现nobody竞然没权限,怪不得会出现上面的问题。
解决问题
定位到问题,接下来解决问题就比较简单了。可以使用两种方式解决这个问题,如下所示。
- 设置任何人都可以写 proxy_temp目录,重启 Nginx 即可解决。
- 直接更改proxy_temp_file_write_size的值,将其修改为大于图片和文件的大小,重启Nginx。
如果是以第一种方式解决问题的话,比如我的proxy_temp目录是/usr/local/nginx/proxy_temp,用如下命令将/usr/local/nginx/proxy_temp目录设置为任何人都可以写,问题解决。
chmod?-R?777?/usr/local/nginx/proxy_temp/?
如果是使用第二种方式解决问题的话,就可以直接修改nginx.conf文件,如下所示。
location?/file?{
?????root?/home/file;
?????index??index.html?index.htm;
?????proxy_set_header?X-Real-IP?$remote_addr;
?????proxy_set_header???Host?$host;
?????proxy_pass?http://127.0.0.1:8080?;
?????client_max_body_size?????100m;
?????client_body_buffer_size??256k;
?????proxy_connect_timeout????1200;
?????proxy_read_timeout???????1200;
?????proxy_send_timeout???????6000;
?????proxy_buffer_size????????32k;
?????proxy_buffers????????????4?64k;
?????proxy_busy_buffers_size??128k;
?????proxy_temp_file_write_size?10m;
}
当然,我也帮这位读者优化了一些其他的配置项。
天津市犀思科技有限公司是专业从事web应用定制开发的一家公司,主营业务包括定制功能型网站建设开发、微信小程序开发、微信公众号开发、APP定制开发、天津企业微信开发、ERP、CRM、OA等企业应用场景信息化解决方案等服务,致力于成为中国领先的IT服务及行业解决方案的提供商。