Вы управляете сайтом на популярной связке Nginx и PHP-FPM, и внезапно ваши пользователи видят холодящую душу надпись «502 Bad Gateway». Это не просто ошибка — это сигнал о разрыве в самом сердце взаимодействия между веб-сервером и обработчиком PHP. В этой статье мы глубоко погрузимся в причины этой неполадки, разберем пошаговый алгоритм диагностики и предоставим практические решения для возвращения вашего проекта в рабочее состояние.
Что на самом деле означает ошибка 502 Bad Gateway?
Ошибка 502 (Bad Gateway) — это статусный код протокола HTTP, который указывает, что один сервер, действуя в роли шлюза или прокси, получил недопустимый ответ от вышестоящего сервера. В контексте связки Nginx + PHP-FPM, Nginx выступает в роли этого шлюза. Он принимает запросы от клиентов (браузеров), но когда пытается передать запрос на обработку в PHP-FPM (FastCGI Process Manager), что-то идет не так, и он получает либо ошибку, либо вообще никакого ответа. В результате пользователю возвращается страница с кодом 502.
Ключевая аналогия: Представьте, что Nginx — это официант в ресторане, а PHP-FPM — повар на кухне. Ошибка 502 возникает, когда официант (Nginx) приходит на кухню, но не может передать заказ повару (PHP-FPM), потому что кухня перегружена, повар не отвечает или дверь на кухню заблокирована.
Основные причины ошибки 502 в связке Nginx и PHP-FPM
Проблема редко бывает в одной точке. Чаще всего это комплекс факторов, которые нужно последовательно исключать.
1. Проблемы с процессом PHP-FPM
Это самая распространенная категория причин.
- Исчерпание дочерних процессов (pm.max_children): В конфигурации PHP-FPM задано ограничение на максимальное количество одновременно работающих процессов. При высокой нагрузке все они могут быть заняты, и новым запросам просто некуда будет «пойти».
- Завершение работы процессов по таймауту (request_terminate_timeout): Если скрипт выполняется дольше, чем задано в этом параметре, PHP-FPM принудительно завершает его. Nginx, не дождавшись ответа, возвращает 502.
- Критические ошибки в PHP-скриптах: Фатальные ошибки (Fatal Error), исчерпание памяти (Allowed memory size exhausted) или бесконечные циклы могут «убивать» рабочий процесс, не возвращая корректного ответа Nginx.
- Неправильные права доступа к сокету: Если PHP-FPM работает через Unix-сокет (а не через TCP-порт), у пользователя, от имени которого работает Nginx (часто www-data или nginx), должны быть права на чтение и запись в этот сокет.
2. Проблемы с конфигурацией Nginx
- Неправильные настройки FastCGI: Ошибки в директивах
fastcgi_pass(неверный путь к сокету или IP-адрес порта),fastcgi_read_timeoutилиfastcgi_send_timeout. - Проблемы с буферами: Слишком маленькие значения
fastcgi_buffersиfastcgi_buffer_sizeдля больших ответов от PHP.
3. Системные ограничения
- Нехватка оперативной памяти (OOM Killer): Когда система исчерпывает память, ядро Linux может принудительно завершить процесс PHP-FPM, чтобы спасти систему от краха.
- Исчерпание лимитов файловых дескрипторов: Каждое соединение использует дескриптор. При их нехватке новые соединения установить не получится.
Пошаговая диагностика и решение
Действуйте последовательно, от простого к сложному.
Шаг 1: Анализ логов — ваш главный инструмент
- Логи ошибок Nginx:
sudo tail -f /var/log/nginx/error.log. Ищите строки с "upstream timed out", "connect() failed", "Connection refused". - Логи PHP-FPM: Обычно
/var/log/php-fpm.logили/var/log/php7.x-fpm.log. Включите логирование в конфиге (php_admin_flag[log_errors] = on). Здесь вы увидите ошибки скриптов. - Системные логи:
sudo journalctl -u php-fpm.service -u nginx.service --since "10 minutes ago"или/var/log/syslog.
Совет: Сразу после появления ошибки 502 проверьте логи. Часто там содержится точное указание на причину, например, "Primary script unknown" (проблема с SCRIPT_FILENAME) или "recv() failed (104: Connection reset by peer)" (процесс PHP-FPM аварийно завершился).
Шаг 2: Проверка статуса и конфигурации PHP-FPM
- Убедитесь, что служба работает:
sudo systemctl status php-fpm. - Перезагрузите конфигурацию:
sudo systemctl reload php-fpm(мягкая перезагрузка). - Проверьте конфигурационный пул (например,
/etc/php/7.4/fpm/pool.d/www.conf). Обратите внимание на ключевые параметры:pm.max_children— увеличьте, если процессы заняты.pm.start_servers,pm.min_spare_servers,pm.max_spare_servers— настройте под вашу нагрузку.request_terminate_timeoutиrequest_slowlog_timeout— увеличьте для тяжелых скриптов.listen— убедитесь, что путь к сокету или порт совпадает с указанным в конфиге Nginx (fastcgi_pass).
Шаг 3: Проверка конфигурации Nginx
В конфиге вашего сайта (например, в /etc/nginx/sites-available/your_site) проверьте блок location ~ \.php$:
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;— путь должен быть верным.- Увеличьте таймауты:
fastcgi_read_timeout 300s;(например). - Убедитесь в наличии обязательных параметров:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;. - Проверьте синтаксис и примените конфиг:
sudo nginx -t && sudo systemctl reload nginx.
Шаг 4: Проверка системных ресурсов
- Память и нагрузка:
free -h,top,htop. - Лимиты для процесса PHP-FPM:
cat /proc/$(pgrep php-fpm | head -1)/limits | grep "open files". - Общие лимиты системы:
ulimit -n.
Профилактика ошибок 502
- Мониторинг: Настройте оповещения о высокой загрузке PHP-FPM или появлении 502 ошибок в логах (например, через Zabbix, Prometheus).
- Кеширование: Внедрите кеширование на уровне Nginx (FastCGI Cache) для статичного контента, чтобы снизить нагрузку на PHP.
- Оптимизация кода: Выявляйте и исправляйте «тяжелые» скрипты, используйте профилировщики (Xdebug, Blackfire).
- Правильный выбор менеджера процессов (pm): Для сайтов с предсказуемой нагрузкой используйте
pm = ondemandилиstatic, для высоконагруженных —dynamicс тонкой настройкой.
FAQ: Часто задаваемые вопросы
Ошибка 502 появляется только иногда, что делать?
Скорее всего, проблема в периодической пиковой нагрузке, которая исчерпывает пул процессов PHP-FPM (pm.max_children) или системные ресурсы. Внимательно изучите логи в момент возникновения ошибки и увеличьте соответствующие лимиты, а также настройте мониторинг.
Как быстро «починить» сайт, если появилась 502?
Самое быстрое решение — перезапустить PHP-FPM: sudo systemctl restart php-fpm. Это освободит зависшие процессы и очистит память. Однако это временная мера, необходимо найти коренную причину.
В чем разница между restart и reload для PHP-FPM?
restart полностью останавливает и запускает службу, обрывая все текущие соединения. reload плавно перезагружает конфигурацию, запуская новые процессы с новыми настройками и постепенно завершая старые, что предпочтительнее для работающего сайта.
Может ли ошибка 502 быть вызвана проблемами с хостингом?
Да, абсолютно. На shared-хостинге вы можете столкнуться с 502 из-за ограничений, наложенных провайдером (лимиты на процессы, память), или из-за проблем на соседних аккаунтах, влияющих на общие ресурсы сервера. В этом случае необходимо обратиться в техподдержку.