进一步思考这个问题,真正的问题是:为什么 Apache 将正在进行的上传放在内存中而不是磁盘上? 我应该能够上传大于服务器可用总内存的文件。
PHP 从未进入方程式,因为上传从未完成,并且 Apache 在将文件传递给 PHP 之前就死机了。
很奇怪。我在 Google 上搜索了好几个小时,却无果。
我有一个 512 MB RAM 的 VPS,我尝试上传 100-250 MB 的文件。100 MB 左右的文件可以正常工作,但超过这个大小就会出现内存问题。
top
这是我尝试上传 130 MB 文件时的输出,此时 PID 18367 即将被终止:
top - 09:43:06 up 6 days, 9:31, 1 user, load average: 0.00, 0.00, 0.00
Tasks: 51 total, 1 running, 50 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.2% us, 0.1% sy, 0.0% ni, 99.8% id, 0.0% wa, 0.0% hi, 0.0% si
Mem: 916144k total, 916144k used, 0k free, 0k buffers
Swap: 0k total, 0k used, 0k free, 0k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
18367 apache 16 0 721m 393m 2288 S 0 44.0 0:01.90 httpd
不知为何它要为 130 MB 的文件使用 393 MB 的内存?(更不用说,只有大约 80% 的文件已上传。)我无法想象 httpd 用所有这些空间做什么。
查看 apache 错误日志,我看到:
[Tue Feb 01 09:43:07 2011] [error] (12)Cannot allocate memory: fork: Unable to fork new process
[Tue Feb 01 09:43:17 2011] [notice] child pid 18367 exit signal Segmentation fault (11)
我不确定这是软件堆栈(CentOS、Apache 和 PHP 通过 mod_fcgid)的限制,还是 Apache 或 PHP 的配置错误。
我确实在我的 vhost.conf 中使用了以下 mod_fcgid 指令,但效果不大:
MaxRequestInMem 1048576
是否有类似的 apache 配置值需要我调整?
感谢您的考虑。
答案1
这是mod_fcgid 中的一个已知错误,但显然mod_fcgid的架构使得很难以全面的方式解决这个问题。
目前,你能做的最好的事情就是升级到 mod_fcgid 2.3.7(或更高版本);它有增强功能至少在文件上传分配内存后的某个时间点释放内存。不过,到目前为止,我的经验是,回收内存可能需要半个小时以上。
答案2
我怀疑这是除了上传器脚本(作者)之外的其他人的限制……
答案3
我以前在 apache+php (使用 horde) 中也遇到过类似的问题。尝试将其添加到您的 apache 配置中:
php_value memory_limit 150M
php_value post_max_size 150M
php_value upload_max_filesize 150M
我不能 100% 确定是否可以在 apache 配置中设置 memory_limit。可能需要在 php.ini 中设置。或者,您也可以设置:
php_value max_execution_time 180
php_value max_input_time 180