Назад | Перейти на главную страницу

Неустранимая ошибка PHP: попытка выделить 47264368 байт

При запуске веб-сайта, размещенного на двух серверах приложений через балансировщик нагрузки, один сервер приложений внезапно перестал работать и завис. Из журнала доступа к другому серверу приложений было обнаружено 499 статусов, а также средняя нагрузка была высокой. Минут через 20 он начал давать статус 200. А затем, когда другой сервер приложений полностью перезагрузился, он также начал нормально работать.

Я не понимал, почему это случилось внезапно. Из журнала ошибок я обнаружил следующую проблему:

2019/11/03 12:43:19 [error] 26445#0: *30538354 FastCGI sent in stderr: "PHP message: PHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 47264368 bytes) in /.........../sites/all/modules/contrib/memcache/dmemcache.inc on line 64" while reading response header from upstream, client: ............, server: .........., request: "................", upstream: "fastcgi://unix:/var/run/php-fpm/php-fpm.sock:", host: "...........", referrer: "..........."

Что мне нужно сделать, чтобы исправить проблему, чтобы она никогда не возникла в будущем?

Вам необходимо увеличить лимит памяти для каждого процесса PHP в вашем php.ini файл. Кажется, сейчас он установлен на 256 МБ. Не забудьте перезагрузить веб-сервер после внесения изменений.

memory_limit = 512M

В более широком смысле, вы не можете выделить память внутри модуля memcache. Это говорит о том, что у вас есть один очень большой кэшированный объект (~ 47 МБ на сообщение об ошибке), который вы пытаетесь загрузить. На сервере, работающем с ограничением памяти 256 МБ, потратить почти 20% ее на один объект не получится.

В Drupal это проявляется в нескольких формах: вам может потребоваться «преодолеть горб», и этот 47 МБ является промежуточным объектом, и в этом случае вы увидите, что простая загрузка страницы прошла успешно, а затем любая, которая зависит от этого объекта размером 47 МБ. терпят неудачу, пока один из них не завершится успешно, затем все нагрузки будут успешными. Или этот объект может быть агломеративным, и в этом случае вы увидите, что запросы начинаются нормально, а затем в течение дня начинают отказываться. Или объект может относиться к определенным частям сайта или даже к определенной локализации. Это действительно сложно понять, и я считаю, что симптомы не всегда совпадают и даже могут казаться недетерминированными.

Для отладки вы можете начать с прямого запроса кэша памяти, чтобы увидеть, что находится в кэше примерно такого размера, или с включения подробного ведения журнала в модуле кэша памяти, чтобы он сообщал вам, что он пытался GET когда это не удалось. См. Раздел «Ведение журнала отладки» эта ссылка чтобы узнать, как это сделать, по крайней мере, в D7. Вы также, вероятно, могли бы вывести некоторый дополнительный контекст из полной трассировки стека, если она у вас есть.

В конце концов, как намекает Берт, Вот, отладка этого может выходить за рамки того, что вы хотели бы сделать. В этом случае увеличение memory_limit непременно устранит проблему. Хотя это кажется легким выходом, имейте в виду, что вопрос о том, повторится ли проблема снова или нет, все равно останется без ответа, пока вы не выполните шаги отладки, описанные выше.