Nova Kwok's Awesome Blog

解决 PHP 处理大型文件时超时的问题

最近在 AreaLoad 的开发中完成了 “收作业” 功能的代码实现,然而在部署到生产环境为 “大数据语言课程实验报告” 收取的时候,在传 $dlcourseid 到后端之后。在完成对学生作业压缩后却发生了 404 的错误,并且服务器上报了一个 abrt 的错误,相关报错信息如下:

ABRT has detected 1 problem(s). For more info run: abrt-cli list --since 1505292199

登上服务器之后吓了一跳,以为 PHP 代码出现了严重的错误。

id 7922bd6e0048c9a0fae2d45ebcc3891c2fc6bd91
reason:         php-fpm killed by SIGSEGV
time:           Tue 12 Sep 2017 12:23:23 AM HKT
cmdline:        'php-fpm: pool www' ''''''''''''''''''''''''''''
package:        php-fpm-7.1.9-1.el7.remi
uid:            994 (nginx)
count:          18
Directory:      /var/spool/abrt/ccpp-2017-09-12-00:23:23-11357


The Autoreporting feature is disabled. Please consider enabling it by issuing
'abrt-auto-reporting enabled' as a user with root privileges

在查看 /var/log/nginx/error.log 的时候发现后端负责处理数据的 course.php 页面的 Notice 甚至无法显示完整就在中间断开了,且有如下错误:

2017/09/13 16:57:02 [error] 13357#0: *2261 open()"/var/www/platform/50x.html"failed (2: No such file or directory), client: 10.8.122.223, server: , request: "POST /python/course.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "10.1.74.133", referrer: "http://10.1.74.133/python/admin.php"
2017/09/13 16:57:43 [error] 13357#0: *2265 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 10.8.122.223, server: , request: "POST /python/course.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "10.1.74.133", referrer: "http://10.1.74.133/python/admin.php"

虽然第一时间想到了可能是 PHP 运行脚本超时,但是在后续的测试中发现我们课程下载的文件 URL 居然会击中学校内容缓存,就开始研究如何部署全局 SSL 了,这个问题一直拖了 3 天,搞的我心神不宁的…

出于不要重复发明轮子的工程思想,AreaLoad 的 Zip 函数模块来自 StackOverflow,但是在花了一个下午对函数进行审计后并没有发现任何可疑的设计问题,且由于在本地测试的数据量较小时尚未报错,所以一直没有想到可能的解决方法。

所幸,Python 实验课足够无聊我得以有时间用来在网上寻找 “最后方案”——Zip 压缩模块的替代品,在 https://gist.github.com/4185113/72db1670454bd707b9d761a9d5e83c54da2052ac 中发现了问题的真正解决方法,原来真的是 PHP 运行时间超时了。在加入了以下两行代码后,问题解决!

ini_set('max_execution_time', 600);
ini_set('memory_limit','1024M');

下一步就是考虑该如何在无法部署合法 SSL 证书的情况下该如何防止学校劫持我们的流量了~

#Chinese #PHP #Areaload