Вы открываете свой сайт, а вместо страницы видите сухое сообщение "502 Bad Gateway" или "502 Bad Gateway nginx". Эта ошибка — частый гость на серверах, где работает связка Nginx и PHP-FPM. Она сигнализирует о разрыве в коммуникации: веб-сервер Nginx не смог получить корректный ответ от бэкенд-процесса PHP-FPM. Это не критическая поломка, а скорее симптом, за которым могут скрываться десятки причин — от нехватки памяти до ошибок в коде. Давайте разберемся, как диагностировать и устранить эту проблему раз и навсегда.
Что такое ошибка 502 Bad Gateway?
В архитектуре современного веба Nginx часто выступает в роли "обратного прокси" или "фронтенд-сервера". Его задача — принимать запросы от браузеров пользователей и передавать их для обработки "бэкенд-серверу", в нашем случае — процессам PHP-FPM (FastCGI Process Manager). Ошибка 502 (Bad Gateway) возникает именно в момент этой передачи, когда Nginx либо не может установить соединение с PHP-FPM, либо получает от него невалидный, пустой или прерванный ответ.
Ключевая аналогия: Представьте, что Nginx — это секретарь на ресепшене, а PHP-FPM — специалист в кабинете. Ошибка 502 означает, что секретарь (Nginx) постучал в дверь кабинета, но либо никто не ответил, либо специалист (PHP-FPM) выкрикнул что-то невнятное и упал в обморок.
Основные причины ошибки 502 в связке Nginx + PHP-FPM
Проблема может крыться как в конфигурации, так и в ресурсах сервера или самом PHP-коде.
1. Проблемы с ресурсами сервера
- Нехватка памяти (RAM/OOM): Самая частая причина. PHP-FPM или система убивают процессы из-за исчерпания оперативной памяти.
- Перегрузка CPU: Сложные скрипты "вешают" процессы PHP-FPM, и они не успевают ответить в заданный таймаут.
- Достигнут лимит файловых дескрипторов: Система не может открыть новые сокеты для соединений.
2. Ошибки в конфигурации Nginx и PHP-FPM
- Неправильные пути к сокету или IP-адресу в директивах
fastcgi_pass. - Слишком маленькие значения таймаутов (
fastcgi_read_timeout,request_terminate_timeout). - Некорректные права доступа к Unix-сокету PHP-FPM.
3. Проблемы с PHP-скриптами и расширениями
- Фатальные ошибки (Fatal Error) в коде, которые аварийно завершают процесс.
- "Бесконечные" циклы или операции, занимающие огромное количество времени.
- Конфликты или падения PHP-расширений (например, opcache, xdebug).
Пошаговая диагностика и решение
Шаг 1: Анализ логов — ваш главный инструмент
Первое, что нужно сделать — проверить логи. Они часто содержат прямую подсказку.
- Логи ошибок Nginx:
sudo tail -f /var/log/nginx/error.log. Ищите строки с "upstream timed out", "Connection refused", "Primary script unknown". - Логи PHP-FPM: Обычно в
/var/log/php-fpm.logили/var/log/php7.x-fpm.log. Здесь могут быть сообщения о "child ... exited on signal", "seems busy" или ошибки сегментации. - Системные логи:
sudo journalctl -xeили/var/log/syslogмогут показать, что ядро (OOM Killer) завершило процесс PHP-FPM из-за нехватки памяти.
Шаг 2: Проверка статуса и конфигурации PHP-FPM
Убедитесь, что служба работает и настроена правильно.
- Проверьте статус:
sudo systemctl status php-fpm(илиphp7.x-fpm). - Перезапустите службу:
sudo systemctl restart php-fpm. - Сравните путь к сокету в конфиге Nginx (
fastcgi_pass unix:/var/run/php/php7.x-fpm.sock;) и в пуле PHP-FPM (listen = /var/run/php/php7.x-fpm.sock). - Проверьте права на сокет:
ls -la /var/run/php/. Владельцем должен быть пользователь и группа, от которых работает PHP-FPM (например, www-data).
Быстрое решение на время диагностики: Увеличьте таймауты в конфиге Nginx (fastcgi_read_timeout 300s;) и в конфиге пула PHP-FPM (request_terminate_timeout = 300). Это поможет, если проблема в "тяжелых" запросах, но не устранит коренную причину.
Шаг 3: Оптимизация ресурсов PHP-FPM
Часто помогает тонкая настройка пулов процессов. Откройте конфиг пула (например, /etc/php/7.x/fpm/pool.d/www.conf) и отрегулируйте ключевые параметры:
pm.max_children: Не ставьте слишком высокое значение. Рассчитывайте по формуле:max_children ≈ (Available RAM) / (Memory per PHP process).pm.start_servers,pm.min_spare_servers,pm.max_spare_servers: Настройте под вашу нагрузку.pm.max_requests: Установите значение (например, 500), чтобы периодически перезапускать процессы и избегать утечек памяти.
Шаг 4: Проверка кода и серверных ограничений
- Включите логирование ошибок PHP (
log_errors = On,error_log = /var/log/php_errors.log) и проверьте их. - Увеличьте лимиты памяти для PHP (
memory_limit = 256M), если скрипты требуют много ресурсов. - Проверьте, не исчерпано ли дисковое пространство (
df -h), особенно в разделе/tmp.
FAQ: Часто задаваемые вопросы
Ошибка 502 появляется только иногда, а не постоянно. В чем дело?
Скорее всего, это проблема с пиковой нагрузкой или утечкой памяти. Проверьте мониторинг нагрузки на CPU и RAM в момент ошибки. Настройте pm.max_requests для циклического перезапуска процессов PHP-FPM.
В логах Nginx ошибка "connect() failed (111: Connection refused)". Что делать?
Это означает, что Nginx не может подключиться к сокету PHP-FPM. Убедитесь, что служба PHP-FPM запущена, а путь к сокету в конфигах Nginx и PHP-FPM абсолютно идентичен. Проверьте права доступа к сокету.
После обновления PHP или установки расширения началась 502 ошибка.
Вероятен конфликт расширений или сбой в конфигурации нового PHP. Отключите недавно установленные расширения, проверьте совместимость версий. Пересоздайте симлинк на сокет после обновления.
Как отличить ошибку 502 из-за нехватки памяти от ошибки таймаута?
Смотрите логи. При нехватке памяти (OOM) в системном логе будет запись от kernel. При таймаутах Nginx запишет "upstream timed out". Также помогает мониторинг в реальном времени командой top или htop.
Может ли ошибка 502 быть вызвана проблемами с базой данных?
Косвенно. Если PHP-скрипт "висит" в ожидании ответа от медленной или недоступной БД, это может привести к превышению таймаута PHP-FPM и, как следствие, к ошибке 502. Проверьте доступность и производительность вашей СУБД.