#Симптомы и отличие от похожих неисправностей
Процессы пула PHP-FPM со временем используют всё больше памяти, а в конфигурации установлен pm.max_requests = 0. Как отличить утечку в приложении от нормального кэширования и настроить перезапуск работников без маскировки проблем. Значение 0 не ограничивает количество запросов, выполняемых одним рабочим процессом. Это не доказательство утечки; pm.max_requests может уменьшить накопление памяти у отдельных работников, но не исправит код, удерживающий большие объекты.
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Код или расширение сохраняет память между запросамиРасход RSS одного дочернего процесса постепенно растёт на одинаковых задачах, даже когда параллелизм невелик. | Один PID накапливает больше RSS после сотен однотипных обращений. | Найти причину в приложении и измерить процесс на повторном тесте. |
Режим static/dynamic запускает слишком много работниковБольшой pm.max_children и pm = static удерживают много процессов, расходуя общую память даже без запросов. | Растёт общая сумма RSS, но каждый процесс примерно одинакового размера. | Проверить режим и разумность числа процессов. |
| Считается память с разделяемыми страницами или кэшемRSS нескольких процессов включает общие страницы; свободная память Linux расходуется на файловый кэш и может освобождаться. | free -h показывает достаточный available, а RSS кажется большой суммой. | Сопоставить available, PSS при наличии инструмента и реальные OOM. |
#Диагностика и пошаговое устранение
- Проверьте, действительно ли память растёт со временемПодключитесь к серверу по SSH из терминала Windows/Linux. Во время низкой нагрузки запишите дату,
free -hи несколько рабочих процессов PHP-FPM; через час при похожем трафике повторите. Фиксируйте PID и RSS конкретных процессов, а не только общий объём, который показывает панель. Если значениеavailableостаётся высоким и страницы отвечают нормально, высокая величина Used сама по себе не означает аварии. - Дополнительная команда по темеLinux · Терминал (Bash)КомандаПросмотровые команды Linux по SSH;
rss— КиБ физической памяти,etime— возраст процесса. По PID можно сравнить один и тот же процесс в двух снимках.date -Isfree -hps -eo pid,ppid,rss,etime,cmd --sort=-rss | head -n 30
- Найдите активные параметры пула и проверьте их смыслВ панели хостинга найдите конфигурацию конкретного пула; выпишите
pm,pm.max_children,pm.max_requestsи приdynamic— настройки числа запасных процессов. Значениеpm.max_requests = 0означает, что принудительного обновления работника по количеству запросов нет. Приstaticвсе работники обычно находятся в памяти постоянно, аondemandсоздаёт и завершает их по потребности. Не меняйте режим и пределы одновременно.
- Измерьте память одного работника до и после одинаковых запросовВ тестовой среде выберите безопасный URL, который не вносит изменения в базу. Сделайте несколько последовательных обращений вручную, фиксируя RSS и PID в
ps. Из-за распределения запросов по разным процессам рост памяти должен подтверждаться на том же PID, иначе вывод преждевременен. При наличииsmemможно смотреть PSS, чтобы не суммировать общую память несколько раз; не устанавливайте новый инструмент на продуктивном сервере без согласования.
- Сопоставьте рост с реальными операциями приложенияПроверьте журнал PHP, долгие запросы, создание изображений, обработку больших JSON, работу OPcache и расширений. Если память растёт после конкретной операции, проверьте результат в профилировщике на тестовом окружении и исправьте накопление объектов или временных массивов. Принудительная перезапись процессов скрывает симптомы, но не является доказательством исправления; возможен и повторный рост с каждым обращением.
- Подберите ограниченный pm.max_requests как временную защитуКогда в одинаковых условиях подтверждён рост памяти отдельного работника и есть резерв CPU, установите в конфигурации пула, например,
pm.max_requests = 500как исходный эксперимент. После 500 обслуженных запросов работник будет заменён, поэтому память накопившегося процесса освобождается при завершении. Реальный интервал подбирайте по замерам: слишком малое число увеличивает стоимость создания процессов и может снизить производительность. Сохраните исходный 0 для отката. - Пример начального испытания, не универсальный нормативINIПример начального испытания, не универсальный норматив. Устанавливать только после измерений и резервной копии конфигурации.
pm.max_requests = 500
- Убедитесь, что проблема не вызвана неподходящим pm.max_childrenЕсли памяти не хватает из-за множества одновременно запущенных процессов, уменьшение интервала
pm.max_requestsмало поможет. Подсчитайте доступный бюджет ОЗУ с учётом БД, OS и остальных сайтов и оцените пределpm.max_childrenотдельно. Не сокращайте его до числа, которое вызывает очереди и 502/504 при обычной нагрузке. При нехватке памяти лучше устранить тяжёлый код и пиковые запросы.
- Проверьте и примените новую конфигурацию аккуратноСделайте копию пула и запустите
sudo php-fpm8.2 -tдля Debian PHP 8.2 либо штатный тест вашей установки. При успехеsudo systemctl reload php8.2-fpm. Если есть ошибка конфигурации, верните 0 из копии и повторите проверку. Отслеживайте перезапуски работников по PID: смена PID после заданного количества запросов нормальна, а частые аварии с SIGSEGV — отдельная проблема.Linux · Терминал (Bash)С осторожностьюНужен sudoПример для Debian 8.2: тест конфигурации обязателен; менять версию и службу в соответствии с сайтом, права администратора. Команда перезагрузки выполняется только при успешной проверке конфигурации (оператор &&). При ошибке исправьте конфигурацию и повторите проверку; не запускайте перезагрузку вручную.sudo php-fpm8.2 -t && sudo systemctl reload php8.2-fpmКоманда может изменить состояние системы или её настройки. Проверьте параметры и последствия перед запуском.
- Наблюдайте не только память, но и задержки после измененияНесколько часов или сопоставимое количество запросов отслеживайте available RAM, возраст работников, количество 502, время ответа и сообщения FPM. Если память стабилизировалась без роста отказов, оставьте согласованное значение и продолжите поиск утечки в тестовой среде. Если процессы пересоздаются слишком часто, а задержки выросли, верните
pm.max_requests = 0, проверьте конфигурацию и reload; передайте разработчику снимки памяти и условия воспроизведения.
#Как проверить результат и что предпринять при неуспехе
Успех — память стабилизируется при сопоставимой нагрузке, нет новых отказов OOM и массовых 502, задержки сайтов не растут. Если память не снижается, проверьте количество одновременно запущенных процессов, общий OPcache и состав приложения; при ухудшении верните прежний параметр из копии.