Веб-серверы и Nginx 9 мин чтения 2026-08-21

Ошибка 502 / 504 Gateway Time-out на Nginx и PHP-FPM: пошаговый поиск причин и решение для нагруженных сайтов

Полный пошаговый гайд системного администратора по диагностике и устранению ошибок 502 Bad Gateway и 504 Gateway Time-out в связке Nginx + PHP-FPM: расшифровка логов, расчет пулов pm.max_children, тюнинг буферов FastCGI, исправление сокетов и защита от OOM Killer.

Инженерная редакция SysKit Проверено инженерами SysKit.ru

Ошибки 502 Bad Gateway и 504 Gateway Time-out — самые распространенные и болезненные проблемы на нагруженных веб-сайтах под управлением связки Nginx и PHP-FPM (WordPress, 1C-Битрикс, OpenCart, Laravel). В часы пикового наплыва посетителей, проведения рекламных кампаний или ночных синхронизаций с 1C/CRM сайт внезапно перестает открываться, отдавая пользователям и поисковым роботам белые экраны с системными кодами сбоя.

Для бизнеса каждая минута простоя — это прямая потеря заказов, слитый рекламный бюджет и падение позиций в поисковой выдаче. Однако многие администраторы совершают грубую ошибку: начинают хаотично перезагружать сервер или наугад накручивать параметры в конфигурационных файлах, лишь усугубляя проблему.

В этом руководстве мы разберем проблему на уровне сетевых сокетов и очередей ядра Linux. Вы получите четкий инженерный алгоритм: от локализации первопричины по логам до формул точного расчета пулов памяти и эталонных конфигураций.

Архитектура сетевого взаимодействия Nginx и пула воркеров PHP-FPM с точками возникновения ошибок 502 и 504
Анатомия взаимодействия: точки падения FastCGI сокета (502 Bad Gateway) и превышения лимитов ожидания (504 Gateway Time-out)
💡
Главное правило инженера: Nginx никогда не генерирует 502 и 504 сам по себе. Nginx выступает лишь обратным прокси-шлюзом (Reverse Proxy). Код 502 означает, что бэкенд (PHP-FPM) упал, недоступен или разорвал соединение до передачи ответа. Код 504 означает, что бэкенд жив, принял запрос, но не успел сгенерировать ответ за отведенный интервал времени. Быстро проверить статус и заголовки ответа вашего сайта можно через наш Анализатор HTTP-заголовков SysKit.

1. В чем разница между 502 Bad Gateway и 504 Gateway Time-out

Чтобы быстро устранить аварию, необходимо понимать физику происходящего на уровне протокола FastCGI:

  • HTTP 502 Bad Gateway (Недопустимый шлюз): Nginx попытался передать HTTP-запрос в апстрим через UNIX-сокет (/run/php/php8.3-fpm.sock) или TCP-порт (127.0.0.1:9000), но соединение было сброшено (Connection reset by peer), сокет отсутствовал (No such file or directory), процесс PHP-FPM был принудительно убит ядром Linux (OOM Killer) или размер HTTP-заголовков ответа превысил выделенный буфер Nginx (too big header).
  • HTTP 504 Gateway Time-out (Время ожидания шлюза истекло): Соединение с PHP-FPM успешно установилось, рабочий процесс принял PHP-скрипт на исполнение, но за отведенное директивой fastcgi_read_timeout время (по умолчанию 60 секунд) PHP-FPM так и не передал HTTP-ответ. Это классический симптом долгих SQL-запросов, внешних API-запросов без таймаута (cURL) или тяжелой генерации отчетов.
Характеристика 502 Bad Gateway 504 Gateway Time-out
Состояние PHP-FPM Остановлен, упал, перегружен, убит по OOM Работает, но заблокирован / завис на вычислениях
Время до отдачи ошибки Мгновенно (0–50 мс) Ровно через значение fastcgi_read_timeout (60с+)
Типичная причина Сбой сокета, нехватка RAM, переполнение очереди Медленный SQL-запрос, зависший cURL, долгий экспорт
Основной лог для проверки /var/log/nginx/error.log, dmesg php-fpm-slow.log, mysql-slow.log

2. Карта логов: точная расшифровка сообщений Nginx и PHP-FPM

Никогда не гадайте о причинах сбоя. В 100% случаев точный диагноз содержится в системных журналах. Откройте терминал сервера и выполните просмотр последних записей:

# 1. Просмотр ошибок Nginx в реальном времени
sudo tail -f -n 50 /var/log/nginx/error.log

# 2. Просмотр системного журнала службы PHP-FPM
sudo tail -f -n 50 /var/log/php8.3-fpm.log
# или через journalctl:
sudo journalctl -u php8.3-fpm -n 50 -f

# 3. Проверка срабатывания OOM Killer в ядре Linux
sudo dmesg -T | grep -i -E "oom|killed process"

Ниже представлена расшифровка наиболее частых записей из /var/log/nginx/error.log:

1. connect() to unix:/run/php/php8.3-fpm.sock failed (111: Connection refused)
Причина: Демон PHP-FPM выключен, упал или сокет не слушается. Решение: sudo systemctl restart php8.3-fpm и проверка статуса.

2. connect() to unix:/run/php/php8.3-fpm.sock failed (2: No such file or directory)
Причина: В конфиге Nginx указан неверный путь к сокету (например, версия php8.1-fpm.sock вместо установленной php8.3-fpm.sock).

3. connect() to unix:/run/php/php8.3-fpm.sock failed (13: Permission denied)
Причина: У пользователя nginx или www-data нет прав на чтение/запись UNIX-сокета. Необходимо проверить директивы listen.owner и listen.group в www.conf.

4. recv() failed (104: Connection reset by peer) while reading response header from upstream
Причина: Рабочий процесс PHP-FPM аварийно завершился прямо во время выполнения скрипта (Segfault, Fatal Error, превышение memory_limit или OOM Killer).

5. upstream sent too big header while reading response header from upstream
Причина: PHP отдал слишком большой объем HTTP-заголовков или множество больших Cookie (часто бывает в 1С-Битрикс и WooCommerce). Буфер FastCGI Nginx переполнился.

6. upstream timed out (110: Connection timed out) while reading response header from upstream
Причина: Истекло время ожидания ответа. PHP-FPM не завершил обработку за время fastcgi_read_timeout.

3. Причина №1: Нехватка воркеров PHP-FPM и расчет pm.max_children

Самая частая причина массовых ошибок 502 на посещаемых сайтах — банальная нехватка рабочих процессов PHP-FPM. Когда все воркеры заняты, новые входящие запросы встают в очередь (listen.backlog). Если очередь заполняется, сокет перестает принимать соединения, и Nginx отдает клиенту 502 Bad Gateway.

В логе /var/log/php8.3-fpm.log это выглядит следующим образом:

[WARNING] [pool www] server reached pm.max_children setting (5), consider raising it

По умолчанию в дистрибутивах Ubuntu/Debian параметр pm.max_children выставлен всего в 5 процессов. Этого достаточно лишь для разработки, но при 20-30 одновременных посетителях сайт моментально падает.

📐
Инженерная формула расчета pm.max_children:
pm.max_children = (Общий объем RAM - RAM под ОС - RAM под MySQL/Redis) / Средний размер процесса PHP

Пример расчета для сервера 4 GB RAM:
1. Под ОС Linux резервируем 512 MB.
2. Под СУБД MySQL/MariaDB резервируем 1024 MB.
3. Доступно для PHP-FPM: 4096 - 512 - 1024 = 2560 MB.
4. Средний размер одного PHP-воркера (WordPress / Bitrix): 50–70 MB.
5. pm.max_children = 2560 MB / 60 MB ≈ 42. Воспользуйтесь нашим готовым конфигуратором PHP-FPM для 4 GB RAM.

Чтобы точно узнать среднее потребление памяти одним PHP-процессом на вашем сервере, выполните команду:

# Средний размер одного процесса php-fpm в мегабайтах (MB)
ps --no-headers -o rss -C php-fpm8.3 | awk '{sum+=$1; count++} END {if (count>0) printf "%.2f MB\n", sum/count/1024; else print "0 MB"}'

Выбор режима менеджера процессов (Process Manager):

  • pm = dynamic (Рекомендуется для большинства сайтов): Воркеры создаются и уничтожаются динамически в зависимости от нагрузки в диапазоне между pm.min_spare_servers и pm.max_children.
  • pm = ondemand (Идеально для серверов с десятками сайтов): Процессы поднимаются только при поступлении запроса и завершаются при простое (pm.process_idle_timeout), экономя RAM.
  • pm = static (Для Highload и выделенных серверов): Фиксированное число воркеров постоянно висит в памяти, исключая накладные расходы процессора на спавн процессов.

4. Причина №2: Зависания скриптов и цепочка таймаутов (504)

Ошибка 504 Gateway Time-out возникает, когда одно из звеньев в цепочке веб-сервера обрывает ожидание раньше, чем скрипт успевает завершиться. В веб-стеке существует строгая иерархия таймаутов, которые должны быть согласованы между собой:

Nginx (fastcgi_read_timeout) >= PHP-FPM (request_terminate_timeout) >= PHP (max_execution_time)
Параметр Где настраивается Значение по умолчанию Рекомендуемое для Production
max_execution_time /etc/php/8.3/fpm/php.ini 30s 60s
request_terminate_timeout /etc/php/8.3/fpm/pool.d/www.conf 0 (выключен) 120s
fastcgi_read_timeout /etc/nginx/nginx.conf (или vhost) 60s 120s - 180s
fastcgi_send_timeout /etc/nginx/nginx.conf 60s 120s

Как найти зависший PHP-скрипт через PHP-FPM Slowlog:

Включите профилирование медленных запросов в файле /etc/php/8.3/fpm/pool.d/www.conf:

; Путь к журналу медленных скриптов
slowlog = /var/log/php-fpm-slow.log

; Фиксировать в логе скрипты, выполняющиеся дольше 5 секунд
request_slowlog_timeout = 5s

; Глубина стек-трейса вызовов
request_slowlog_trace_depth = 20

После перезагрузки PHP-FPM (systemctl reload php8.3-fpm) в файле /var/log/php-fpm-slow.log будут появляться точные файлы, функции и номера строк кода, на которых зависает выполнение (например, медленный запрос к БД через mysqli_query() или вызов внешнего API через curl_exec()).

5. Надежные VDS-серверы под нагруженные PHP-проекты

Для стабильной работы динамических PHP-приложений критически важны два фактора: высокая тактовая частота процессора (CPU Single-Core Frequency) для быстрой генерации страниц и сверхбыстрые NVMe накопители с задержками I/O менее 0.05 мс. Ниже представлены проверенные облачные платформы, оптимизированные для стека Nginx + PHP + MySQL:

Рекомендуемые VDS-провайдеры

Отказоустойчивые сервера с быстрыми NVMe и каналом до 1 Гбит/с

🔷 Selectel VPS / VDS
Выбор под Highload от 200 ₽

Премиальная KVM-виртуализация на скоростных процессорах Intel Xeon / AMD EPYC, серверные NVMe SSD диски, 3 ТБ бесплатного трафика на 1 Гбит/с порту и дата-центры Tier III в РФ.

Конфигурация
от 1 vCPU / 1 GB RAM / 10 GB NVMe (до 64 vCPU / 256 GB RAM)
Timeweb Cloud
Максимальная частота до 5.0 GHz

Высокочастотные процессоры High-Freq (до 5.0 GHz), идеальные для быстрой компиляции PHP и работы 1С-Битрикс/WordPress, автоматические снимки дисков и поминутная тарификация.

Конфигурация
от 1 vCPU / 2 GB RAM / 30 GB NVMe
🟠 Beget VPS
Простота управления и CMS

Легкое развертывание LEMP-стека и баз данных в 1 клик через встроенную панель управления, круглосуточная квалифицированная поддержка 24/7 и стабильный аптайм 99.98%.

Конфигурация
от 1 vCPU / 2 GB RAM / 35 GB NVMe

6. Причина №3: Размер буферов FastCGI (Upstream sent too big header)

Еще одна неочевидная причина ошибки 502 Bad Gateway на сайтах со сложной авторизацией, корзинами покупок или фреймворками (Bitrix, Symfony, Laravel) — превышение лимитов буферизации заголовков FastCGI.

По умолчанию в Nginx размер буфера под заголовки ответа составляет всего 4k или 8k (размер одной страницы памяти). Если приложение передает длинные сессионные Cookie, JWT-токены или служебные заголовки отладки, Nginx не может прочитать заголовок целиком и мгновенно возвращает клиенту ошибку 502 со следующим логом:

[error] 14210#14210: *8451 upstream sent too big header while reading response header from upstream, client: 198.51.100.4, server: example.com, request: "GET /personal/orders/ HTTP/2.0", upstream: "fastcgi://unix:/run/php/php8.3-fpm.sock:"

Как исправить:
Добавьте в секцию location ~ .php$ или блок http {} файла /etc/nginx/nginx.conf увеличенные буферы:

location ~ .php$ {
    try_files $uri =404;
    fastcgi_split_path_info ^(.+.php)(/.+)$;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

    # Исправление ошибки "upstream sent too big header" и ускорение I/O:
    fastcgi_buffer_size 128k;
    fastcgi_buffers 256 16k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;

    # Таймауты ожидания ответа
    fastcgi_connect_timeout 60s;
    fastcgi_send_timeout 120s;
    fastcgi_read_timeout 120s;
}

7. Причина №4: Сокеты, права www-data и лимиты ядра Linux

Способ взаимодействия между Nginx и PHP-FPM определяет общую пропускную способность сервера. Доступно два варианта:

  1. UNIX Domain Socket (unix:/run/php/php8.3-fpm.sock): Работает через оперативную память ядра без оверхеда сетевого стека TCP/IP. Обеспечивает на 15–25% меньшую задержку (latency) и экономит ресурсы CPU. Оптимален, когда Nginx и PHP-FPM работают на одном сервере.
  2. TCP/IP Socket (fastcgi_pass 127.0.0.1:9000;): Использует локальный сетевой стек. Необходим при разделении Nginx и PHP-FPM по разным серверам или контейнерам Docker.

Частая ошибка прав доступа на UNIX-сокет:
Если после перезагрузки сервера в логе появляется (13: Permission denied), проверьте конфигурацию /etc/php/8.3/fpm/pool.d/www.conf. Параметры владельца сокета должны соответствовать пользователю Nginx:

; Пользователь и группа для прослушивания сокета
listen = /run/php/php8.3-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

Тюнинг лимитов ядра Linux (Kernel somaxconn & backlog):
При тысячах одновременных подключений очередь сокета ядра может переполняться. Увеличьте системные лимиты в /etc/sysctl.conf:

# Добавьте в конец файла /etc/sysctl.conf:
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
fs.file-max = 2097152

# Примените настройки без перезагрузки:
sudo sysctl -p

И синхронизируйте очередь в www.conf: установите listen.backlog = 65535.

Инженерная карта пошаговой диагностики ошибок Nginx и PHP-FPM
Инженерная карта: пошаговый алгоритм локализации сбоев по записям в error.log и системным метрикам

8. Причина №5: OOM Killer и утечки оперативной памяти

Если в логе Nginx вы видите recv() failed (104: Connection reset by peer), а сервис PHP-FPM периодически самопроизвольно перезапускается — с вероятностью 90% сервер столкнулся с нехваткой RAM, и защитный механизм ядра Linux Out of Memory (OOM) Killer принудительно убил процесс PHP.

Проверьте системный журнал ядра командой:

sudo dmesg -T | grep -i -E "oom|killed process"

Если вывод содержит строки вида Out of memory: Kill process 18452 (php-fpm8.3) score 428 or sacrifice child, предпримите следующие шаги:

  1. Подключите Swap-файл: Если на сервере 1–2 GB RAM, временная нехватка памяти моментально вызывает падение. Создайте swap размером 2–4 GB на быстром NVMe диске.
  2. Ограничьте memory_limit в php.ini: Не выставляйте memory_limit = -1 или 2048M без острой необходимости. Для WordPress/OpenCart достаточно 256M, для 1С-Битрикс — 512M.
  3. Включите перезапуск воркеров от утечек памяти: В www.conf задайте pm.max_requests = 1000. После обработки 1000 HTTP-запросов процесс PHP-FPM мягко завершится и освободит накопленную память, исключая постепенную деградацию сервера.
  4. Включите OPcache: Кэширование байткода PHP в памяти снижает нагрузку на CPU на 70% и ускоряет отклик сайта в 3–5 раз (смотрите наш гайд Оптимизация PHP OPcache).

9. Готовые эталонные конфигурации Nginx и PHP-FPM

Ниже собраны готовые к использованию в продакшене шаблоны конфигураций, протестированные под высокой нагрузкой.

1. Оптимальный пул PHP-FPM (/etc/php/8.3/fpm/pool.d/www.conf для сервера 4 GB RAM):

[www]
user = www-data
group = www-data

listen = /run/php/php8.3-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
listen.backlog = 65535

; Динамический менеджер воркеров
pm = dynamic
pm.max_children = 40
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 15
pm.max_requests = 1000

; Защита от зависаний
request_terminate_timeout = 120s

; Логирование медленных скриптов
slowlog = /var/log/php-fpm-slow.log
request_slowlog_timeout = 5s
request_slowlog_trace_depth = 20

; Системные лимиты
rlimit_files = 65535
catch_workers_output = yes

2. Оптимальный блок FastCGI в Nginx (/etc/nginx/conf.d/php.conf):

# Глобальные параметры буферизации FastCGI
fastcgi_buffer_size 128k;
fastcgi_buffers 256 16k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;

# Таймауты шлюза
fastcgi_connect_timeout 60s;
fastcgi_send_timeout 120s;
fastcgi_read_timeout 120s;

# Обработка сбоев бэкенда (автоматический переход на кэш при 502/504)
fastcgi_next_upstream error timeout invalid_header http_500 http_503;
fastcgi_next_upstream_tries 3;
fastcgi_next_upstream_timeout 10s;

10. Сводная матрица поиска и быстрого устранения неисправностей

Код ошибки и симптом Локализация в логах Первопричина сбоя Действие инженера
502 Bad Gateway 111: Connection refused Служба PHP-FPM остановлена или упала systemctl restart php8.3-fpm, проверка синтаксиса
502 Bad Gateway 13: Permission denied Nginx не имеет прав на сокет Установить listen.owner = www-data в www.conf
502 Bad Gateway server reached max_children Все воркеры заняты, очередь переполнена Увеличить pm.max_children по формуле памяти
502 Bad Gateway too big header Заголовки ответа не влезли в буфер Задать fastcgi_buffer_size 128k; в Nginx
502 Bad Gateway 104: Connection reset by peer Воркер убит по OOM Killer / Fatal Error Проверить dmesg, добавить swap, снизить memory_limit
504 Gateway Time-out 110: Connection timed out Скрипт завис на SQL-запросе или cURL Включить slowlog, оптимизировать индексы БД, поднять timeout

11. Резюме и чек-лист стабильности

Ошибки 502 и 504 — это не приговор, а четкий индикатор того, что инфраструктура сайта требует балансировки ресурсов и синхронизации параметров стека. Регулярно проводите аудит логов и придерживайтесь проверенного чек-листа:

✅ Чек-лист отказоустойчивости LEMP-стека:

  • Параметр pm.max_children рассчитан строго по доступной физической RAM.
  • Задано значение pm.max_requests = 1000 для защиты от утечек памяти.
  • Увеличены буферы FastCGI (fastcgi_buffer_size 128k).
  • Согласована цепочка таймаутов (Nginx >= PHP-FPM >= PHP).
  • Включен журнал медленных запросов slowlog (от 5 секунд).
  • Настроен Swap-раздел на случай кратковременных всплесков трафика.
  • Включен и настроен OPcache (opcache.memory_consumption = 256).
  • Настроена ротация логов (Logrotate для Nginx и PHP), чтобы диск не переполнился.

⚠️ Типичные антипаттерны:

  • Увеличение max_children без оглядки на RAM: Если задать 200 воркеров на сервере с 2 GB памяти, при первом наплыве трафика OOM Killer положит весь сервер.
  • Завышение таймаутов до 600 секунд: Это маскирует тормозящие SQL-запросы, воркеры остаются заблокированными на 10 минут, и пул мгновенно исчерпывается.
  • Использование pm = static на слабых VPS: Пустая трата оперативной памяти при отсутствии реального трафика.

Нужен надежный сервер без сбоев и просадок производительности?

Разверните оптимизированный VDS с аппаратной KVM-изоляцией, процессорами до 5.0 GHz и скоростными NVMe дисками на Selectel.

Развернуть высоконагруженный VDS на Selectel →

Вопросы и ответы (FAQ)

Популярные вопросы вебмастеров и сисадминов по данной теме

Почему сайт отдает 502 только при пиковом наплыве посетителей?
Это классический признак исчерпания пула воркеров PHP-FPM (лимит pm.max_children). Все свободные процессы заняты обработкой запросов, новые посетители встают в очередь listen.backlog, и при её переполнении Nginx мгновенно возвращает ошибку 502 Bad Gateway. Решение — пересчитать pm.max_children по доступной оперативной памяти и включить FastCGI-кэширование статических страниц.
Чем отличается 504 Gateway Time-out от 502 Bad Gateway с точки зрения диагностики?
При 502 бэкенд не вернул никакого HTTP-ответа (упал, выключен, разорвал соединение или сбросил сокет). Ошибка 502 происходит почти мгновенно. При 504 процесс PHP-FPM жив и работает, но скрипт не успевает закончить выполнение за время fastcgi_read_timeout (обычно 60 секунд) из-за тяжелых SQL-запросов или внешних API. Ошибка 504 отдается ровно после истечения таймаута.
Что делать, если в логе Nginx появляется 'upstream sent too big header'?
Эта ошибка означает, что объем HTTP-заголовков или Cookie, переданных PHP-скриптом, превысил стандартный буфер Nginx. Для исправления добавьте в блок location ~ \.php$ директивы fastcgi_buffer_size 128k; fastcgi_buffers 256 16k; fastcgi_busy_buffers_size 256k; и выполните reload Nginx.
Как настроить Nginx, чтобы сайт не падал в 502 при перезапуске PHP-FPM?
Используйте директиву fastcgi_next_upstream error timeout invalid_header http_500 http_503; а также подключите микрокэширование FastCGI с параметром fastcgi_cache_use_stale updating error timeout invalid_header http_500 http_502 http_503;. В этом случае во время перезагрузки или пикового сбоя PHP-FPM Nginx будет мгновенно отдавать пользователям сохраненную версию страницы из кэша.

Читайте также в блоге SysKit

Смежные руководства и полезные технические статьи