Вы управляете сайтом на популярной связке Nginx и PHP-FPM, и вдруг пользователи начинают жаловаться на загадочную ошибку «502 Bad Gateway». Страницы не грузятся, вместо них — раздражающее сообщение об ошибке. Это не просто технический сбой — это сигнал о нарушении коммуникации между ключевыми компонентами вашего веб-сервера. Давайте разберемся, что скрывается за этой ошибкой, как ее диагностировать и, главное, как надежно исправить.
Что такое ошибка 502 Bad Gateway?
Ошибка 502 (Bad Gateway) — это код состояния HTTP, который означает, что один сервер, выступающий в роли шлюза или прокси, получил недопустимый ответ от вышестоящего сервера. В контексте связки Nginx + PHP-FPM, Nginx выступает в роли этого шлюза. Он принимает запросы от браузеров пользователей, но когда пытается передать запрос на обработку PHP-скриптов серверу PHP-FPM (FastCGI Process Manager), что-то идет не так, и Nginx получает ошибку или вообще не получает ответа.
Ключевая аналогия: Представьте, что Nginx — это секретарь на ресепшене, а PHP-FPM — это специалист в кабинете. Секретарь (Nginx) принимает вопросы посетителей (HTTP-запросы) и передает их специалисту (PHP-FPM). Если специалист не отвечает, заперт в кабинете или кричит что-то невнятное, секретарь не может дать внятный ответ посетителю и говорит: «Извините, не могу связаться со специалистом» (502 Bad Gateway).
Основные причины ошибки 502 в связке Nginx и PHP-FPM
Проблема почти всегда кроется в «обрыве связи» между Nginx и PHP-FPM. Вот главные виновники:
1. Проблемы с самим PHP-FPM
- Служба PHP-FPM остановлена или не запущена: Самая банальная и частая причина.
- Исчерпание ресурсов (детей-воркеров): В конфигурации PHP-FPM (обычно в файле
www.conf) задано ограничение на количество одновременных процессов (pm.max_children). При высокой нагрузке все процессы могут быть заняты, и новым запросам просто не хватит «свободных рук». - Критические ошибки в PHP-скриптах: Скрипт может «падать», вызывая фатальную ошибку (Fatal Error) или превышая лимит времени/памяти до того, как отправит ответ.
- Неправильные настройки сокета или порта: Nginx настроен на подключение к несуществующему сокету или порту.
2. Проблемы с таймаутами
request_terminate_timeoutв PHP-FPM: Если выполнение скрипта превышает это значение, PHP-FPM принудительно завершает процесс.fastcgi_read_timeoutв Nginx: Время, которое Nginx ждет ответа от PHP-FPM. Если ответ не пришел за это время, Nginx возвращает 502.
3. Проблемы с правами доступа
Nginx (работающий от пользователя, например, www-data или nginx) должен иметь права на чтение/запись в Unix-сокет PHP-FPM (если используется сокет) или возможность подключиться к TCP-порту.
Пошаговая диагностика и решение
Шаг 1: Проверка статуса службы PHP-FPM
Первым делом убедитесь, что служба работает. В терминале выполните:
systemctl status php-fpm # или php7.4-fpm, php8.1-fpm в зависимости от версии
Если служба неактивна, запустите ее: systemctl start php-fpm.
Шаг 2: Анализ логов — ваш главный инструмент
- Логи Nginx (ошибок):
/var/log/nginx/error.log. Ищите строки с "upstream timed out" или "connect() failed". - Логи PHP-FPM: Обычно
/var/log/php-fpm.logили в системном журнале (journalctl -u php-fpm). Здесь могут быть сообщения о нехватке памяти, достиженииmax_childrenили фатальных ошибках в скриптах.
Совет: Сразу после появления ошибки 502 проверьте логи. Часто там содержится точное указание на причину, например, "recv() failed (104: Connection reset by peer)" что часто указывает на падение процесса PHP-FPM из-за ошибки в скрипте или нехватки памяти.
Шаг 3: Проверка и корректировка конфигурации
Сравните настройки в блоке location ~ \.php$ вашего конфига Nginx (например, /etc/nginx/sites-available/your-site) с фактическими параметрами PHP-FPM.
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; # Или 127.0.0.1:9000
fastcgi_read_timeout 60s; # Увеличьте при медленных запросах
... # остальные fastcgi_param
}
Убедитесь, что путь к сокету или адрес порта совпадают с настройками в конфиге PHP-FPM (/etc/php/8.1/fpm/pool.d/www.conf). Ищите параметры listen =.
Шаг 4: Оптимизация лимитов PHP-FPM
В файле www.conf обратите внимание на ключевые параметры пула:
pm.max_children: Рассчитывайте примерно:Общая доступная память / Средний размер памяти на процесс PHP.pm.start_servers,pm.min_spare_servers,pm.max_spare_servers: Настройте под вашу нагрузку.request_terminate_timeoutиrequest_slowlog_timeout: Увеличьте для тяжелых операций.
После изменений перезагрузите конфигурацию: systemctl reload php-fpm и nginx -s reload.
Шаг 5: Проверка ресурсов сервера
Используйте top, htop или free -m. Возможно, серверу банально не хватает оперативной памяти или процессор загружен на 100%, что приводит к зависаниям.
Профилактика ошибок 502
- Настройте мониторинг (например, с помощью UptimeRobot или самописных скриптов), который будет проверять доступность не только главной страницы, но и «тяжелого» PHP-эндпоинта.
- Регулярно обновляйте PHP, Nginx и ваше приложение.
- Используйте кэширование (OPcache для PHP, кэш страниц в Nginx) для снижения нагрузки на PHP-FPM.
- Пишите оптимизированный код и настройте корректные лимиты выполнения для фоновых задач.
FAQ — Часто задаваемые вопросы
Ошибка 502 появляется только иногда, а не всегда. В чем дело?
Скорее всего, это проблема с лимитами процессов (pm.max_children) или таймаутами. Ошибка возникает в моменты пиковой нагрузки, когда все процессы PHP-FPM заняты, или когда какой-то конкретный скрипт выполняется дольше обычного. Проверьте логи в момент возникновения ошибки.
Я увеличил pm.max_children, но ошибка не исчезла. Что делать?
Увеличение max_children без контроля может привести к исчерпанию памяти. Проверьте, хватает ли серверу ОЗУ. Возможно, проблема в конкретном «сломанном» скрипте, который «роняет» воркер PHP-FPM. Внимательно изучите логи PHP-FPM на предмет фатальных ошибок (Fatal error).
В чем разница между использованием сокета (unix socket) и порта (127.0.0.1:9000)?
Unix-сокет часто работает немного быстрее, так как не использует сетевой стек. Однако при проблемах с правами доступа или в сложных виртуализированных средах иногда надежнее использовать TCP-порт (localhost). Если перешли с одного метода на другой, не забудьте поправить настройки в Nginx и PHP-FPM и перезапустить службы.
Ошибка 502 возникает после обновления PHP. Как исправить?
1. Убедитесь, что новая версия PHP-FPM запущена (имя службы могло измениться, например, php8.2-fpm).
2. Проверьте, что в конфиге Nginx в директиве fastcgi_pass указан корректный путь к сокету новой версии.
3. Проверьте совместимость вашего приложения с новой версией PHP.