По-видимому, случайная ошибка исчерпания памяти

У меня странная проблема, которую мне трудно отладить. У меня есть приложение, написанное на Symfony2, распределенное на трех веб-серверах за балансировщиком нагрузки. На каждом из веб-серверов есть экземпляр Varnish.

В случайное время некоторые из веб-серверов - один или два, редко все из них - отвечают ошибкой 503 на домашней странице в течение примерно 10 минут, а затем все возвращается в норму.

Ошибка вызвана фатальной ошибкой допустимого размера памяти PHP. Но чего я не понимаю, так это почему одно и то же приложение с тем же кодом, подключением к одной и той же БД и т. д. дает сбой в один момент за другим, а затем снова возвращается в нормальное состояние. И даже одно и то же приложение на разных серверах с одним и тем же оборудованием и программным обеспечением одновременно ведет себя по-разному.

Мое первое предположение заключалось в том, что срок действия кеша Varnish истек на неисправных серверах, в то время как на тех, которые вели себя нормально, все еще была кэширована свежая копия без ошибок. Но если я вручную очищаю кеш на всех серверах, серверы, на которых не было ошибок, отвечают 200 OK, и кеш успешно регенерируется, в то время как другие продолжают давать сбой.

И чтобы стать еще более странным... Я понял, что один и тот же URL-адрес, который не работает с некоторыми случайными аргументами запроса, правильно отвечает с некоторыми другими. Я имею в виду аргументы, которые ничего не делают в коде.

У меня заканчиваются идеи о том, как отладить эту проблему. Любая подсказка будет по-настоящему оценена. Спасибо!

ОБНОВЛЕНИЕ: я также использую Memcached для кэширования запросов и результатов Doctrine. Ошибка исчерпания памяти возникает, когда Doctrine пытается что-то сохранить в Memcached. Первое предположение состоит в том, что он пытается сохранить очень большой результат, но это все еще не объясняет, почему он дает сбой на одном веб-сервере, в то время как на других нет проблем, и все они обрабатывают одни и те же запросы из одной и той же БД.


person Guido Kritz    schedule 19.01.2015    source источник
comment
Если бы мне пришлось угадывать, APC заполняется и паникует.   -  person castis    schedule 20.01.2015
comment
@castis Вау, я забыл упомянуть, что использую кеш кода операции, и я понятия не имел, что это может вызвать ошибку исчерпания памяти на PHP. Я обязательно посмотрю на это! Я дам вам знать, если это решит проблему. Большое спасибо.   -  person Guido Kritz    schedule 20.01.2015
comment
@castis на самом деле я использую Opcache, а не APC. Я попытался сбросить Opcache во время возникновения ошибки, но это не помогло.   -  person Guido Kritz    schedule 28.01.2015


Ответы (1)


Для меня это звучит так, как будто у вас есть некоторые плохо работающие PHP-скрипты и/или слишком высокая максимальная разрешенная память для PHP. Memory_limit * максимальное количество процессов с запасом около 15 МБ на процесс никогда не должно превышать доступную память. Если вам нужно больше памяти для некоторых запросов, вы должны настроить дополнительный пул с меньшим количеством максимальных процессов.

Также примите во внимание, что лак может занимать довольно большой кусок памяти. Ограничьте размер кеша и максимальное количество одновременных подключений. Каждое соединение использует память, но объем сильно зависит от вашего VCL и размера запроса (включая заголовки).

Это может стать проще в обращении и наверняка повысит эффективность кэширования, если вы поместите лак на слой балансировщика нагрузки.

person Clarence    schedule 22.01.2015
comment
Возможно, я ошибаюсь, но, насколько я понимаю, ошибка «Разрешенный размер памяти исчерпан» не имеет ничего общего с максимальным количеством процессов или общей доступной памятью. Если бы это было проблемой, я думаю, что ошибка была бы «Недостаточно памяти». - person Guido Kritz; 28.01.2015