前段时间上线的一个web系统,运行一直比较稳定,但这两天开始出现后台导出数据时,浏览器console报NET::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK)错误,百思不得其解,但初步判断应该是和导出的数据量增大有关。通过搜索,得到了以下线索:
- 磁盘空间不足
- nginx缓存配置不足
- 目录权限问题
本系统web架构很简单,nginx + php-fpm + mysql。同时,我在后端的运行日志里没找到请求记录。因此初步判定应该是在nginx这一端出了问题,对以上线索逐一排查。
磁盘空间直接df -h就可看到,没有问题。
nginx缓存配置的确没有设置,那么就是用的默认的了。尝试在server节点增加以下配置:
proxy_buffering on;
proxy_buffer_size 1024k;
proxy_buffers 100 1024k;
proxy_busy_buffers_size 2048k;
大致意思就是开启代理缓冲,设置缓冲区大小为1024k,当nginx代理从后端获取到响应后,会把内容缓冲到这里,如果超过缓冲区大小,就会落盘缓冲。
重启nginx后,问题没得到解决,囧~~
核对了一下,导出的文件内容也不会超过1M,按照这个配置,理论上也不会用到磁盘缓冲,就不会有目录权限问题了?
再次跟踪nginx的error日志,发现了可疑的地方:
39211#0: *2144 open() "/dir/nginx/fastcgi_temp/1/00/0000000001" failed (13: Permission denied)
这很明显就是目录权限问题了,但为什么nginx的buffer配置“没生效”呢?仔细看,这是fastcgi_temp目录,不是proxy_temp目录哦,至此真相大白!
是后端nginx的fastcgi代理缓冲满了,它要落盘的目录是fastcgi_temp,而nginx启动的用户没有目录权限造成的。默认的fastcgi缓冲配置是这样的:
fastcgi_buffers 8 4/8K;
fastcgi_buffer_size 4K;
本次导出文件大小在150k左右,所以出现了以上问题。
这也就是为什么之前运行正常,数据量大了导出的时候就出错的原因了。
解决办法:
1、增大fastcgi缓冲区大小
2、增加fastcgi_temp目录权限
更多内容可参考:
http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html