php下载15万条数据的csv文件的解决方案
今天来总结一下解决了下载16万条数据到csv文件的问题。主要是消费报表,用于财务对账,需要下载成excel文件,我们是下载成.csv文件,遇到数据量大的商家,一个月的消费数据超过15万条,经常就下载进度到99%卡住 ,其实后台已经报错500或者504。
今天彻底解决了下载15万8千多条数据不成功的问题,当然之前还出现过内存溢出的问题,后来找到瓶颈,优化了代码,解决了内存溢出的问题。
以前的代码是将数据库取的2万条数据没按分页取,直接一下子取出来,然后将数据拼装成csv文件所需要的整块的data,也就是不是逐行写入,第一次浪费内存是在将数据存放在array中,第二次浪费内存是将数据拼装成array再往csv文件中写,所以内存溢出。优化方案是扩大php内存,然后优化代码,php默认的内存128M太小,相对于下载20w条数据的业务来说,所以内存扩大到1G。代码优化方案:将取数据改成分页取,每10000条取一次,然后foreach这一万条数据,一边拼装一边往csv文件中写,fputcsv($fp, $row); 这样优化以后, 下载8万条数据不会报内存溢出。
将下载这个特殊的action的内存扩大,
ini_set('memory_limit', '1G');//将内存最大限制改为1G
之后就不再出现内存溢出了,但是数据量在11万条以上时,仍然下载不成功,查日志发现是PHP Fatal error: Maximum execution time of 30 seconds exceeded in /xx/xx 目录,所以解决办法是在这个下载的action里前面加上一句:
set_time_limit(0);//不设置超时时间
然后再执行下载,发现php里不再报错,但是页面端返回504超时。在页面的response里能看到提示的是nginx报错,去nginx日志里查,果然有Fatal的错误:
2017/10/31 15:25:03 [error] 15639#0: *696311 upstream timed out (110: Connection timed out) 。
然后找到运维同事,帮忙修改一下服务器nginx的配置,反向代理超时,下载15万8千多条数据成功。
修改配置就是:
NGINX反向代理的超时报错,解决方法:
server {
listen *:80;
location ~ .*\.(php|php5)?$
{
fastcgi_pass 127.0.0.1:9001;
fastcgi_index index.php;
fastcgi_read_timeout 200;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi.conf;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
}
生效的主要就是那个fastcgi_read_timeout时间。改成了200,测试下载158500条数据没问题。
下一篇: Java集合框架之fastutil