Как исправить ошибку 503 Service Temporarily Unavailable на Nginx

Полное руководство по устранению ошибки 503 в Nginx: от диагностики по чек-листу до тонкой настройки таймаутов, балансировки нагрузки и health checks. Готовые команды и примеры конфигурации.

Ошибка 503 — это статус, который Nginx возвращает, когда не может обработать запрос из-за временной недоступности backend-сервиса. Чаще всего это происходит из-за таймаутов, недоступности всех серверов в upstream или исчерпания ресурсов. В этом руководстве — алгоритм действий от простого к сложному: от срочного чек-листа до настройки таймаутов, балансировки и мониторинга для предотвращения проблем.

Чек-лист диагностики ошибки 503 в Nginx

Используйте диагностические вопросы в начале статьи, чтобы определить, с какого пункта этого списка стоит начать проверку. Если причина неочевидна или требуется полный аудит, выполняйте пункты последовательно.

Выполните пункты по порядку, чтобы найти причину:

  1. Синтаксис и конфигурация:
    • sudo nginx -t – есть ли ошибки в конфигах?
    • Проверьте адрес в proxy_pass и доступность серверов в upstream.
  2. Доступность бэкенда:
    • curl -I http://backend_host:port/ – отвечает ли бэкенд HTTP-кодом 200?
  3. Логи:
    • sudo tail -f /var/log/nginx/error.log – ищите connect() failed, upstream timed out.
    • Проверьте логи самого backend-приложения.
  4. Нагрузка и ресурсы:
    • htop, df -h – нет ли нехватки памяти, CPU или дискового пространства?
  5. Тайм-ауты (распространённая причина):
    • Увеличьте proxy_read_timeout в конфигурации Nginx до 120s и перезагрузите сервис.

Понимание ошибки 503 Service Temporarily Unavailable

Код 503 указывает на проблему на стороне сервера. Ниже — типичные причины.

Причины ошибки 503

Ошибка 503 — следствие сбоя в цепочке обработки запроса. Причины делятся на три категории:

  1. Проблемы с backend-сервером (частая причина):

    • Перегрузка приложения: Backend (например, PHP-FPM, Node.js, Gunicorn) исчерпал лимиты процессов/потоков или не справляется с объёмом запросов.
    • Сбой сервиса: Сам backend-процесс упал (критическая ошибка, завершение работы).
    • Зависимости недоступны: Backend не подключается к базе данных, кешу (Redis) или внешнему API.
  2. Проблемы с настройкой или лимитами Nginx:

    • Некорректные таймауты: Значения proxy_read_timeout или proxy_connect_timeout установлены слишком низко для медленного backend-приложения.
    • Исчерпание ресурсов Nginx: Достигнут лимит файловых дескрипторов (worker_rlimit_nofile) или одновременных соединений (worker_connections).
    • Ошибка в конфигурации: Неправильный адрес в proxy_pass, синтаксическая ошибка в блоке upstream.
  3. Проблемы с инфраструктурой и ресурсами:

    • Нехватка системных ресурсов: Серверу не хватает оперативной памяти (OOM Killer завершает процессы), процессор загружен на 100%, или заполнено дисковое пространство (часто это раздел /tmp или место под логи).
    • Сетевые проблемы: Файрвол блокирует соединения между Nginx и backend на уровне сети или портов.

Базовые сценарии и первые диагностические вопросы

Используйте таблицу, чтобы быстро определить источник проблемы и перейти к нужному шагу решения.

СимптомВероятная причинаПервые действияСледующий шаг
Ошибка возникает внезапно для всех пользователей.Полный сбой backend-сервиса, исчерпание системных ресурсов, изменение конфигурации Nginx.Проверьте логи Nginx на connect() failed.Шаг 2: Проверка доступности backend
Ошибка возникает периодически или под нагрузкой.Нехватка процессов/потоков в backend-приложении, малые таймауты в Nginx, достижение лимитов соединений.Проверьте логи Nginx на upstream timed out.Шаг 3: Быстрая диагностика нагрузки и ресурсов
Ошибка только для определённых запросов (загрузка файлов, API).Слишком малая задержка proxy_read_timeout для долгих операций, нехватка дискового пространства на backend.Проверьте время выполнения проблемных запросов в backend.Шаг 4: Проверьте и настройте таймауты прокси
Ошибка появилась после обновления конфигурации или деплоя.Ошибка в новой конфигурации Nginx, неудачный деплой backend-приложения.Проверьте синтаксис конфигурации NginxШаг 1: Проверка конфигурации Nginx

Проверьте логи ошибок Nginx (/var/log/nginx/error.log). Ищите сообщения:

Поиск неисправностей и устранение ошибки 503

Шаг 1. Проверьте конфигурации Nginx

Начните с проверки файлов конфигурации Nginx. Проверьте блок server, конфигурацию upstream и настройки proxy. Неправильная конфигурация вызывает ошибку 503. Внесите необходимые изменения и перезапустите Nginx.

На что обратить внимание:

  1. proxy_pass: Убедитесь, что директива указывает на корректный адрес и порт backend-сервера. Пример: proxy_pass http://backend_server;
  2. upstream: Проверьте, что серверы в блоке upstream доступны и нет синтаксических ошибок. Пример некорректной записи: server backend1.example.com:8080 max_fails=3;.
  3. proxy_next_upstream: Укажите, при каких ошибках Nginx выбирает следующий сервер. Для обработки 503 ошибок добавьте http_500 http_502 http_503 http_504.

Проверьте синтаксис и перезагрузите конфигурацию:

sudo nginx -t  # Проверка синтаксиса
sudo systemctl reload nginx # Безопасная перезагрузка конфигурации

Шаг 2. Проверьте подключения backend сервера

Проверьте, что backend серверы доступны. Проверьте доступность backend-сервера с помощью сетевых утилит и HTTP-запросов:

  1. Базовая сетевая доступность: ping -c 4 backend_ip_or_hostname
  2. Проверка порта: nc -zv backend_ip port или telnet backend_ip port
  3. Проверка HTTP-ответа: curl -I http://backend_ip:port/ или curl -I http://backend_hostname/

Код ответа 200 OK или HTTP/1.1 200 означает, что сервер работает. Ответы 5xx, таймауты или ошибки соединения указывают на проблему на стороне бэкенда.

Шаг 3. Быстрая диагностика нагрузки и ресурсов

Цель: За 2 минуты понять, не исчерпаны ли CPU, память, дисковое пространство или лимиты соединений.

Выполните следующие команды на сервере с Nginx и, если возможно, на backend-сервере:

  1. Загрузка CPU и памяти:

    # Общая картина (нажмите 'q' для выхода)
    top -bn1 | head -20
    # Или смотрим доступную память
    free -h | grep -i "available\|пямять"

    Тревожные признаки: load average > числа ядер CPU, значение available памяти близко к 0.

  2. Дисковое пространство:

    # Проверяем, не заполнены ли критичные разделы
    df -h / /tmp /var/log

    Тревожный признак: Использование (Use%) любого раздела > 95%.

  3. Сетевые соединения Nginx (возможное исчерпание лимитов):

    # Считаем активные соединения Nginx
    sudo ss -tanp state ESTABLISHED | grep -c nginx

    # Быстрая проверка лимитов (сравните с числом выше)
    cat /proc/$(cat /var/run/nginx.pid 2>/dev/null || pgrep -o nginx)/limits 2>/dev/null | grep "open files"

    Тревожный признак: Число активных соединений близко к лимиту open files для процесса Nginx.

Что делать, если найдена проблема:

Шаг 4. Проверьте и настройте таймауты прокси (самая частая причина)

Цель: Убедиться, что Nginx не обрывает соединение с медленным backend.

  1. Найдите блок location, который проксирует запросы на backend.

  2. Убедитесь, что заданы адекватные таймауты. Если их нет — добавьте:

    location / {
    proxy_pass http://your_backend;
    proxy_connect_timeout 5s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s; # Ключевой параметр!
    }
  3. Если backend обрабатывает долгие операции (загрузка файлов, отчёты), увеличьте proxy_read_timeout:

    proxy_read_timeout 120s;  # или 300s для очень долгих задач
  4. Примените изменения:

    sudo nginx -t && sudo systemctl reload nginx

Шаг 5. Проверьте пассивные health checks в upstream

Цель: Убедиться, что Nginx временно исключает неработающие бэкенды из пула.

  1. Найдите блок upstream в конфигурации.

  2. Убедитесь, что для серверов заданы max_fails и fail_timeout:

    upstream backend_pool {
    server backend1:80 max_fails=3 fail_timeout=30s;
    server backend2:80 max_fails=3 fail_timeout=30s;
    }
  3. Проверьте, что в location есть директива proxy_next_upstream:

    location / {
    proxy_pass http://backend_pool;
    proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
    }
  4. Если этих настроек нет — добавьте их и перезагрузите Nginx. Это позволит избежать ошибки 503 при кратковременных сбоях одного из backend-серверов.

Предотвращение возникновения ошибки 503 в будущем

Настройте мониторинг и анализируйте логи

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

Анализ этих данных выявит паттерны, приводящие к ошибке 503 (например, рост времени ответа перед сбоем).

Внедрение балансировки нагрузки

Балансировка нагрузки распределяет трафик, что предотвращает перегрузку одного сервера и позволяет обслуживать запросы, даже если один из бэкендов упал. В Nginx встроенный механизм балансировки с помощью блока upstream.

Базовая конфигурация upstream в Nginx:

http {
upstream backend_pool {
# Метод балансировки 'least_conn' направляет трафик на сервер с наименьшим числом активных соединений
least_conn;

# Перечисляем backend-серверы. Параметр 'weight' задаёт приоритет (необязательно)
server backend1.example.com:80 weight=3 max_fails=2 fail_timeout=30s;
server backend2.example.com:80 weight=2 max_fails=2 fail_timeout=30s;
server 192.168.1.10:8080 backup; # Резервный сервер, используется, если основные недоступны
}

server {
listen 80;
location / {
# Перенаправляем весь трафик в определённый пул серверов
proxy_pass http://backend_pool;
proxy_set_header Host $host;
}
}
}

Главные параметры и методы балансировки:

Настройте пассивные проверки состояния backend серверов

В open-source версии Nginx нет встроенных активных health checks (эта функция доступна только в платной версии Nginx Plus). Однако вы можете использовать пассивные проверки — механизм, при котором Nginx автоматически отслеживает доступность backend-серверов на основе результатов реальных пользовательских запросов.

Как настроить пассивные проверки:

upstream backend_pool {
# Сервер исключается из балансировки после 3 неудачных попыток
# Возвращается в работу через 30 секунд
server backend1.example.com:80 max_fails=3 fail_timeout=30s;
server backend2.example.com:80 max_fails=3 fail_timeout=30s;

# Резервный сервер (используется при недоступности основных)
server backup.example.com:8080 backup;
}

server {
location / {
proxy_pass http://backend_pool;

# Какие ошибки считать "неудачными попытками":
proxy_next_upstream error timeout invalid_header
http_500 http_502 http_503 http_504
;

# Лимиты на переключение между серверами:
proxy_next_upstream_tries 2; # Максимум 2 попытки на другой сервер
proxy_next_upstream_timeout 30s; # Общий таймаут на все попытки
}
}

Как это работает:

  1. Обнаружение проблемы: Если запрос к backend-серверу завершается:
    • Ошибкой соединения (connection refused, timeout)
    • HTTP-кодом 5xx (500, 502, 503, 504)
    • Истечением таймаута proxy_read_timeout
  2. Подсчёт неудач: Nginx увеличивает счётчик неудачных попыток для этого сервера.
  3. Исключение из пула: После достижения max_fails (в примере: 3) подряд неудач сервер помечается как недоступный.
  4. Временная пауза: На fail_timeout секунд (в примере: 30s) трафик не направляется на этот сервер. Запросы автоматически перенаправляются на другие серверы в upstream.
  5. Автовосстановление: После истечения fail_timeout Nginx снова попробует отправить запрос на «выздоровевший» сервер. Если он успешен — сервер возвращается в пул.

Проверка работы пассивных проверок:

# 1. Остановите один из backend-серверов
sudo systemctl stop backend.service

# 2. Отправьте несколько запросов через Nginx
for i in {1..5}; do curl -I http://ваш-сайт/; done

# 3. Проверьте логи Nginx на сообщения об исключении сервера
sudo tail -f /var/log/nginx/error.log | grep -i "no live upstreams\|upstream temporarily disabled"

# 4. Через 30 секунд (fail_timeout) сервер автоматически вернётся в пул
# 5. Запустите backend и убедитесь, что ошибки 503 прекратились
sudo systemctl start backend.service

Планирование ресурсов и масштабирование

Если ошибки 503 возникают из-за нехватки ресурсов, используйте следующие стратегии:

Заключение

Как показано в руководстве, ошибка 503 обычно возникает из-за проблем за пределами веб-сервера: отказа приложения, исчерпания системных ресурсов или некорректных сетевых настроек.

Для быстрого устранения инцидента используйте чек-лист диагностики: проверьте логи Nginx на наличие ошибок соединения или таймаутов, убедитесь в доступности бэкенда и проверьте нагрузку на сервер. В большинстве случаев проблема решается увеличением таймаутов прокси (proxy_read_timeout), настройкой пассивных проверок здоровья (max_fails, fail_timeout) или оптимизацией системных лимитов.

Чтобы предотвратить повторение ошибок в будущем, внедрите проактивные меры:

Системный подход — от оперативной диагностики по чек-листу до настройки health checks и балансировки — позволяет не только устранять сбои, но и построить систему, которая автоматически исключает неисправные серверы и выдерживает рост нагрузки.

Комментарии


Дополнительные материалы

Предыдущая Статья

Новое в Symfony 6.4: Больше тестируемых утверждений

Следующая Статья

Новое в Symfony 6.4: Улучшения локали