Веб-серверы и Nginx 14 мин чтения 2026-10-11

Сбой 503 Service Unavailable: причины в Nginx, Apache и PHP-FPM, перегрузка воркеров, настройка очередей и страниц техобслуживания

Инструкция по диагностике и ликвидации сбоя 503 Service Unavailable: анализ логов Nginx и FPM, расширение очередей somaxconn, расчет пула воркеров и настройка Maintenance Mode с заголовком Retry-After.

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

Внезапное появление кода ошибки 503 Service Unavailable (Служба временно недоступна) — один из самых неприятных сценариев в жизни веб-проекта. В отличие от тривиальных синтаксических ошибок в коде, этот сбой возникает в моменты наивысшей ценности сайта: во время успешных рекламных кампаний, пиковых распродаж, наплыва поисковых ботов или выкатки плановых релизов. Посетители видят сухую заглушку браузера, рекламные бюджеты тратятся впустую, а конверсии падают до нуля.

С точки зрения стандарта RFC 9110 (HTTP Semantics) статус 503 сообщает клиенту: веб-сервер исправен и понимает запрос, однако в текущий момент он физически не в состоянии его обработать из-за временной перегрузки вычислительных мощностей либо проведения технических регламентных работ. В этой практической инструкции мы разберем корни проблемы на уровне очередей ядра Linux, научимся выявлять перегруженные пулы PHP-FPM и Apache, а также настроим отказоустойчивый режим техобслуживания с сохранением позиций в поиске Яндекса и Google.

1. Анатомия ошибки 503: отличие от 500, 502 Bad Gateway и 504 Gateway Timeout

Для быстрой локализации проблемы системному администратору необходимо четко различать смежные серверные коды ошибок 5xx. Каждая из них указывает на конкретный уровень программного стека:

Код ошибки Стандартное название Где произошел сбой Физическая причина проблемы
500 Internal Server Error Бэкенд-приложение Фатальная ошибка в коде PHP/Node.js, необработанный Exception или сбой директив в файле .htaccess.
502 Bad Gateway Промежуточный шлюз Nginx в роли прокси получил невалидный, поврежденный или пустой ответ от upstream-бэкенда (сбой протокола, некорректные HTTP-заголовки или аварийный сброс процесса до завершения ответа).
503 Service Unavailable Очередь веб-сервера / FPM Сервер осознанно отказывает в обработке: исчерпан пул воркеров, переполнена очередь сокетов или включен режим обслуживания.
504 Gateway Timeout Таймаут прокси Бэкенд принял запрос, но не успел вернуть ответ за время fastcgi_read_timeout (зависший SQL-запрос, долгий цикл).

💡 Ключевое свойство ошибки 503

Код 503 — единственный статус перегрузки, который регламентирован для легитимного временного отключения сайта. Если вместе с кодом 503 передать HTTP-заголовок Retry-After: 3600, поисковые боты не понизят позиции сайта, а браузеры клиентов смогут автоматически повторить попытку отправки запроса.

2. Локализация сбоя: чтение логов Nginx, Apache и пулов PHP-FPM

Первое действие при появлении жалоб на ошибку 503 — чтение диагностических журналов. Разные звенья стека фиксируют эту проблему с характерными сигнатурами.

1. Диагностика в логах Nginx (/var/log/nginx/error.log)

Если Nginx выступает фронтендом перед PHP-FPM или Apache, при переполнении очередей в логах появляются следующие записи:

# Сигнатура 1: сокет PHP-FPM переполнен и не принимает новые соединения
connect() to unix:/run/php/php8.3-fpm.sock failed (11: Resource temporarily unavailable) while connecting to upstream

# Сигнатура 2: исчерпаны соединения в upstream-пуле
no live upstreams while connecting to upstream, client: 203.0.113.195, server: example.com

Сообщение 11: Resource temporarily unavailable прямо указывает на то, что очередь соединений ядра Linux (backlog) переполнена, и ядро отбрасывает новые входящие соединения от Nginx.

2. Диагностика в логах PHP-FPM (/var/log/php8.3-fpm.log)

В главном журнале менеджера процессов PHP-FPM ищите предупреждения о нехватке воркеров:

# Сигнатура: все воркеры заняты, входящие запросы становятся в очередь
[WARNING] [pool www] server reached pm.max_children setting (10), consider raising it

Если данное предупреждение появляется регулярно в часы пик, это означает, что 10 выделенных процессов обрабатывают запросы медленнее, чем поступают новые. Очередь накапливается за секунды, вызывая отказ в обслуживании.

3. Диагностика в логах Apache (/var/log/apache2/error.log)

Если на сервере используется Apache со связкой mod_php или mpm_event, перегрузка выглядит следующим образом:

# Сигнатура Apache: исчерпаны рабочие процессы пула
[mpm_event:error] [pid 1234] AH00484: server reached MaxRequestWorkers setting, consider raising the MaxRequestWorkers setting
[proxy:error] [pid 1235] AH00959: ap_proxy_connect_backend disabling worker for (127.0.0.1)

Зафиксировав сигнатуру в журналах, можно сразу переходить к точному устранению узкого места без слепого изменения конфигураций наугад.

3. Тюнинг очередей сокетов: параметры somaxconn ядра Linux и listen.backlog в PHP-FPM

Когда все процессы PHP-FPM заняты выполнением скриптов, новые входящие подключения не сбрасываются мгновенно, а помещаются в очередь ожидания сокета (Listen Backlog). Однако по умолчанию в большинстве дистрибутивов Linux (Ubuntu, Debian) размер этой очереди ограничен крошечным значением 128 или 511.

При всплеске трафика очередь заполняется за доли секунды, после чего ядро Linux начинает отклонять входящие пакеты, возвращая веб-серверу ошибку 11: Resource temporarily unavailable.

Для устранения узкого места необходимо согласовать параметры очереди на системном и прикладном уровнях:

1. Тюнинг системной очереди сокетов ядра Linux

Проверим текущий системный лимит очереди сокетов:

# Просмотр текущего лимита
sysctl net.core.somaxconn

Настроим параметры сетевого стека в файле /etc/sysctl.d/99-network-tuning.conf:

# /etc/sysctl.d/99-network-tuning.conf
# Максимальный размер очереди невыбранных подключений (1024–2048 для средних сайтов, 4096 для Highload)
net.core.somaxconn = 4096

# Очередь неполных TCP-соединений (SYN backlog)
net.ipv4.tcp_max_syn_backlog = 4096

# Максимальное количество пакетов в очереди сетевого интерфейса
net.core.netdev_max_backlog = 4096

Применим изменения без перезагрузки сервера:

sudo sysctl --system

💡 Роль очереди Backlog в архитектуре

Параметр listen.backlog — это буфер для сглаживания кратковременных всплесков (микропиков), пока рабочие процессы FPM освобождаются от выполнения предыдущих задач. Увеличение очереди спасет от отказа при секундных скачках, но не решит проблему нехватки производительности, если скрипты заблокированы долгими SQL-запросами или внешними API.

2. Настройка сокета и пула в PHP-FPM (pool.d/www.conf)

Перед изменением пула обязательно измерьте реальное потребление оперативной памяти процессами вашей CMS:

# Точный замер среднего размера активных воркеров PHP-FPM в мегабайтах (RSS)
ps -ylC php-fpm8.3 --sort:rss | awk '{sum+=$8; count++} END {print "Средний RSS:", sum/count/1024, "MB"}'

В типовых блогах процесс может занимать 35–45 МБ, а в интернет-магазинах на WooCommerce или 1С-Битрикс средний вес воркера легко достигает 80–120+ МБ. Подставляйте в формулу именно ваши замеренные значения.

Откроем конфигурацию пула /etc/php/8.3/fpm/pool.d/www.conf:

; Размер очереди слушающего сокета (согласован с net.core.somaxconn)
listen.backlog = 4096

; Режим управления процессами (dynamic для предсказуемых нагрузок)
pm = dynamic

; Максимальное количество одновременно запущенных воркеров по формуле
pm.max_children = 35

; Количество процессов при старте службы
pm.start_servers = 8

; Минимальное количество свободных процессов в резерве
pm.min_spare_servers = 4

; Максимальное количество свободных процессов в резерве
pm.max_spare_servers = 12

; Перезапуск воркера после обработки 1000 запросов для защиты от утечек памяти
pm.max_requests = 1000
# Проверка конфигурации и мягкая перезагрузка пула
sudo php-fpm8.3 -t && sudo systemctl reload php8.3-fpm

4. Настройка Nginx: балансировка upstream, таймауты и защита от лавинообразной перегрузки

Чтобы фронтенд-сервер Nginx не стал узким местом до того, как запрос дойдет до PHP-FPM, необходимо синхронизировать лимиты соединений с системными дескрипторами файлов в /etc/nginx/nginx.conf:

# /etc/nginx/nginx.conf
user www-data;
worker_processes auto;

# Системный лимит открытых файловых дескрипторов для воркеров Nginx
worker_rlimit_nofile 8192;

events {
    # Количество одновременных соединений на один рабочий процесс (согласовано с somaxconn)
    worker_connections 2048;
    multi_accept on;
}

На уровне виртуального хоста добавим пул постоянных соединений keepalive для снижения накладных расходов при передаче запросов в FastCGI:

upstream php_backend {
    # Путь к локальному Unix-сокету
    server unix:/run/php/php8.3-fpm.sock max_fails=3 fail_timeout=10s;
    
    # Пул постоянных открытых соединений для исключения оверхеда на сокетах
    keepalive 32;
}

server {
    listen 80;
    server_name example.com;

    location ~ .php$ {
        include fastcgi_params;
        fastcgi_pass php_backend;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;

        # Таймауты взаимодействия
        fastcgi_connect_timeout 5s;
        fastcgi_send_timeout 30s;
        fastcgi_read_timeout 60s;

        # Перехват ошибок бэкенда для возврата оформленной страницы 503
        fastcgi_intercept_errors on;
        error_page 503 /maintenance.html;
    }
}

5. Выбор аппаратных ресурсов VDS для устойчивости к всплескам трафика

Устойчивость веб-приложения к сбою 503 напрямую зависит от баланса аппаратных ресурсов виртуального сервера (VDS):

Уровень нагрузки Лимит pm.max_children Очередь backlog Рекомендуемая конфигурация VDS
Стандартный проект (блог, корпоративный сайт, визитка) 15–20 воркеров 1024 1–2 vCPU • 2 ГБ RAM
Базовый сервер, стабильно выдерживает до 10 000–20 000 посещений в сутки при наличии кэширования.
Нагруженный e-Commerce (WooCommerce, 1С-Битрикс, API) 40–80 воркеров 4096 2–4 vCPU • 4–8 ГБ RAM
Высокочастотные ядра (3.3+ ГГц), быстрые NVMe-накопители и выделенный пул под буфер СУБД.

Для проектов, регулярно проводящих промо-акции и рассылки, ключевым фактором является базовая частота процессора: высокочастотные ядра 3.3+ ГГц обрабатывают каждый запрос быстрее, сокращая время удержания воркера FPM и освобождая очередь для следующих клиентов.

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

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

Выбор редакции
⚡

Timeweb Cloud — Быстрые NVMe VDS для Highload

Высокочастотные процессоры от 3.3 до 5.0 ГГц, мгновенное масштабирование ресурсов и защита от перегрузок при наплыве посетителей.

Конфигурация
2 vCPU 3.3+ ГГц • 2 ГБ RAM • 30 ГБ NVMe • Трафик без лимита
Премиум Tier III
🔷

Selectel — Корпоративные облачные серверы Tier III

Гарантированные ресурсы vCPU без переподписки (No Overcommit), приватные сетевые каналы и надежность дата-центров Tier III.

Конфигурация
2 vCPU • 4 ГБ RAM • 40 ГБ NVMe • Дата-центры Tier III
Простота и стабильность
🟠

Beget — Простота управления и автоматические бэкапы

Готовые шаблоны веб-серверов Nginx + PHP-FPM, мониторинг системных ресурсов в реальном времени, бесплатные ежедневные бэкапы и техподдержка 24/7.

Конфигурация
2 vCPU • 2 ГБ RAM • 30 ГБ NVMe • Бесплатные бэкапы

6. Регламентное обслуживание без потери SEO: настройка страницы 503 с заголовком Retry-After

Когда на сайте необходимо провести обновление ядра CMS, миграцию базы данных или изменение структуры каталога, проект временно переводят в режим обслуживания (Maintenance Mode). Однако многие разработчики совершают грубейшую ошибку: они отдают страницу-заглушку с кодом ответа 200 OK или ставят временный редирект 302 Found на отдельную страницу /maintenance/.

Для поисковых систем (Яндекс, Google) это оборачивается катастрофой:

  • Если отдать код 200: поисковый робот решит, что старый контент страниц безвозвратно удален, и проиндексирует текст заглушки («Сайт на техобслуживании»), выбросив исходные сниппеты и ключевые слова из топа поисковой выдачи.
  • Если отдать код 302: поисковик может склеить все страницы сайта с URL заглушки, обнулив ссылочный вес.

Единственный канонический способ проведения регламентных работ без ущерба для SEO — возврат статуса HTTP 503 Service Unavailable совместно со служебным заголовком Retry-After.

Настроим безопасный режим техобслуживания в виртуальном хосте Nginx с возможностью беспрепятственного доступа для IP-адреса администратора:

# Определение исключений для IP-адресов администраторов
geo $maintenance_bypass {
    default 0;
    198.51.100.25 1;  # Доверенный статический IP администратора
    127.0.0.1     1;  # Локальный лупбэк
}

server {
    listen 80;
    server_name example.com;
    root /var/www/example.com/public;

    # Проверка флага техобслуживания и исключения администратора
    set $maintenance 0;
    if (-f $document_root/maintenance.flag) {
        set $maintenance 1;
    }
    if ($maintenance_bypass = 1) {
        set $maintenance 0;
    }

    # Возврат статуса 503 при активном флаге
    if ($maintenance = 1) {
        return 503;
    }

    # Обработка страницы 503 с обязательным заголовком Retry-After
    error_page 503 @maintenance_view;
    location @maintenance_view {
        # Рекомендуем роботам повторить визит через 1 час (3600 секунд)
        add_header Retry-After 3600 always;
        add_header Cache-Control "no-store, no-cache, must-revalidate" always;
        rewrite ^(.*)$ /maintenance.html break;
    }

    location ~ .php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }
}

Теперь для активации регламентных работ достаточно создать пустой файл-флаг одной командой:

# Включение режима обслуживания
touch /var/www/example.com/public/maintenance.flag

# Выключение режима обслуживания после завершения работ
rm /var/www/example.com/public/maintenance.flag

Посетители и поисковые боты получат валидный статус 503 с красивой HTML-страницей и указанием времени возобновления работы, а администратор продолжит беспрепятственно работать с сайтом и тестировать обновления.

7. Устранение блокировок в бэкенде: файловые сессии PHP, медленные SQL-запросы и внешние API

Зачастую ошибка 503 возникает даже при умеренной посещаемости, когда воркеры PHP-FPM не перегружены вычислениями, а просто «висят» в ожидании заблокированных ресурсов. В результате все процессы исчерпываются, и новые клиенты получают отказ в обслуживании.

Три наиболее частые причины скрытых блокировок:

1. Блокировка файловых сессий PHP (Session Lock)

По умолчанию PHP сохраняет пользовательские сессии в локальных файлах и при вызове session_start() накладывает эксклюзивную блокировку (flock) на файл сессии. Если пользователь открывает страницу, отправляющую параллельные AJAX-запросы, или выполняет долгую операцию (генерация PDF, выгрузка отчета), все последующие запросы от этого пользователя блокируются и удерживают воркеры FPM.

💡 Как решить проблему блокировки сессий

1. В коде длительных скриптов закрывайте запись сессии сразу после чтения данных вызовом session_write_close();.
2. Перенесите хранилище сессий из файловой системы в Redis: связка с Redis поддерживает неблокирующий быстрый доступ и разгружает диск.

2. Долгие блокировки таблиц и транзакций в СУБД

Зависший SQL-запрос удерживает подключение к базе данных. Воркер PHP-FPM переходит в состояние ожидания I/O, занимая слот в пуле. Настройте в MySQL директиву innodb_lock_wait_timeout = 35 (по умолчанию 50 с). Не опускайте это значение ниже 30 секунд без анализа профиля нагрузки, иначе вы рискуете аварийно оборвать легитимные тяжелые транзакции (генерацию отчетов, выгрузку каталогов или системные миграции БД).

3. Зависания на внешних HTTP-запросах через cURL

Если бэкенд синхронно обращается к сторонним API (платежные шлюзы, CRM, сервисы доставки) без жестко заданного таймаута, сбой на стороне внешнего шлюза приведет к зависанию всех процессов вашего сайта. Всегда устанавливайте жесткие таймауты: CURLOPT_TIMEOUT => 5 и CURLOPT_CONNECTTIMEOUT => 2.

4. Мониторинг очереди сокетов и статуса воркеров в реальном времени

Чтобы оперативно зафиксировать переполнение очереди до того, как клиенты увидят ошибку 503, используйте встроенные системные утилиты:

# Проверка размера очереди сокета PHP-FPM (Recv-Q показывает число ожидающих запросов)
ss -l -x | grep php

# Проверка счетчиков переполнения очередей на уровне ядра Linux (listen queue overflow)
netstat -s | grep -i "listen"

Для постоянного мониторинга активируйте страницу статуса FPM в www.conf (директива pm.status_path = /status) и отслеживайте метрики listen queue (текущая очередь) и active processes (число занятых воркеров).

8. Итоговый чек-лист администратора по предотвращению и устранению сбоя 503

Для гарантированной защиты сайта от перегрузок и ошибок 503 выполните комплексную проверку сервера по чек-листу:

📋 Чек-лист отказоустойчивости веб-сервера

  • Проверены журналы /var/log/nginx/error.log и /var/log/phpX.X-fpm.log на наличие сигнатур Resource temporarily unavailable и pm.max_children.
  • Системные очереди сокетов увеличены: net.core.somaxconn = 4096 и net.ipv4.tcp_max_syn_backlog = 4096 в /etc/sysctl.d/.
  • В пуле FPM скорректирован параметр listen.backlog = 4096 (согласован с системным лимитом).
  • Выполнен реальный замер RSS-памяти воркеров через ps, и лимит pm.max_children рассчитан точно под объем свободной RAM сервера.
  • В Nginx согласованы параметры worker_connections 2048; и системный лимит дескрипторов worker_rlimit_nofile 8192;.
  • Включен пул постоянных соединений keepalive 32; в блоке upstream Nginx.
  • Настроена регулярная проверка переполнения очередей сокетов через ss -l -x и страницу статуса /status FPM.
  • Для планового техобслуживания настроена отдача статуса HTTP 503 с обязательным заголовком Retry-After и исключением для IP администратора.
  • Сессии PHP перенесены в Redis либо закрываются через session_write_close().
  • Таймаут ожидания блокировок MySQL innodb_lock_wait_timeout выставлен во взвешенном диапазоне 30–45 с.
  • Проконтролирован код ответа и скорость отдачи через онлайн-инструмент Проверка хостинга и времени ответа сервера.
  • Проверена корректность цепочек перенаправлений через Проверка цепочек редиректов HTTP.

Разверните отказоустойчивый веб-сервер на надежном VDS

Защитите свой проект от падений при всплесках трафика: выберите высокочастотные серверы с быстрыми NVMe-дисками и гарантированными ресурсами у проверенных провайдеров.

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

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

В чем ключевая разница между ошибками 502 Bad Gateway и 503 Service Unavailable?
Ошибка 502 (Bad Gateway) возникает, когда Nginx в роли промежуточного прокси-шлюза получает от вышестоящего сервера (upstream) невалидный, поврежденный или пустой ответ (включая аварийное падение процесса бэкенда до завершения HTTP-ответа). Ошибка 503 (Service Unavailable) означает, что сервер доступен и работоспособен, но осознанно отказывает в обработке запроса прямо сейчас: либо из-за переполнения очередей сокетов (backlog) и нехватки свободных воркеров, либо из-за включенного режима регламентного техобслуживания.
Почему при регламентных работах на сайте нужно возвращать именно HTTP 503, а не 200 или 302?
Если во время технических работ сайт отдает код 200 с заглушкой «Сайт на обновлении», поисковые роботы Яндекса и Google решат, что контент страниц удален, и перезапишут сниппеты в поисковой выдаче. При возврате статуса 503 с заголовком Retry-After поисковики понимают, что недоступность временная, не трогают текущие позиции и приходят на повторную переиндексацию позже.
Какая директива PHP-FPM чаще всего является причиной спонтанной ошибки 503 при наплыве трафика?
Основной причиной является исчерпание лимита pm.max_children в конфигурации пула /etc/php/X.X/fpm/pool.d/www.conf совместно с маленьким размером сокетной очереди listen.backlog. Когда все воркеры заняты обработкой тяжелых запросов, а очередь сокета переполняется, ядро Linux начинает сбрасывать входящие соединения, вызывая ошибку 503 или 502.

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

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