Если подумать об этом больше, то действительно возникает вопрос: почему Apache помещает незавершенную загрузку в память, а не на диск? Я должен иметь возможность загрузить файл, размер которого превышает общий объем памяти, доступной серверу.
PHP никогда не участвует в уравнении, так как загрузка никогда не заканчивается, а Apache умирает, прежде чем сможет передать файл в PHP.
Очень странно. Я гуглил часами, но безрезультатно.
У меня есть VPS с 512 МБ оперативной памяти, и я пытаюсь загрузить файлы размером от 100 до 250 МБ. Файлы размером примерно до 100 МБ работают нормально, но если что-то закончится, у меня возникнут проблемы с памятью.
Вот результат top
когда я пытаюсь загрузить файл 130 МБ, непосредственно перед уничтожением 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
Каким-то образом он использует 393 МБ памяти для файла 130 МБ? (Не говоря уже о том, что было загружено только около 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.
Я использую следующую директиву mod_fcgid в моем vhost.conf, но без особого эффекта:
MaxRequestInMem 1048576
Есть ли аналогичные значения конфигурации apache, которые мне следует настроить?
Спасибо за внимание.
Это известная ошибка в mod_fcgid, но очевидно, что архитектура mod_fcgid затрудняет комплексное решение этой проблемы.
На данный момент лучшее, что вы можете сделать, - это перейти на mod_fcgid 2.3.7 (или новее); Это есть улучшения чтобы хотя бы освободить память в какой-то момент после того, как выгрузка файла выделит ее. По моему опыту, восстановление памяти может занять до получаса.
Я видел подобные проблемы раньше с apache + php (с horde). Попробуйте добавить в конфигурацию apache:
php_value memory_limit 150M
php_value post_max_size 150M
php_value upload_max_filesize 150M
Я не уверен на 100%, можно ли установить memory_limit в конфигурации apache. Возможно, его нужно установить в php.ini. По желанию вы также можете установить:
php_value max_execution_time 180
php_value max_input_time 180
Я сомневаюсь, что это чьи-то еще ограничения, кроме сценария загрузки (автора (ов))…