Перейти к основному содержимому

Руководства / Коды состояния HTTP: разбор

502 Bad Gateway: что сломалось за прокси и как это найти

502 Bad Gateway означает, что прокси перед вашим сайтом запросил у бэкенда ответ и получил что-то невалидное, либо вообще ничего. Прокси работает правильно; он сообщает, что то, что стоит за ним, недоступно, падает или говорит не на том протоколе.

Кто возвращает 502 и почему

RFC 9110 определяет 502 для сервера, выступающего шлюзом или прокси, который получил невалидный ответ от внутреннего сервера, к которому обращался, пытаясь выполнить запрос. В любом современном стеке есть хотя бы один такой переход: nginx или Apache перед сервером приложения, балансировщик нагрузки перед флотом серверов, CDN перед вашим источником, либо все три сразу.

Эта многослойность - ключ к чтению 502. Компонент, который ответил, достаточно здоров, чтобы сформировать страницу ошибки. Компонент за ним - нет. Так что 502 всегда делит ваш стек на рабочую половину и сломанную, и ваша задача - определить, где проходит граница.

Соседние коды говорят о более узких вещах. 504 Gateway Timeout означает, что бэкенд был доступен, но слишком медленным. 500 означает, что сам бэкенд выполнился и выбросил ошибку. 502 означает, что бэкенд дал плохой ответ либо не дал никакого. Полное сравнение - в обзоре 5xx.

Распространенные причины

  • Процесс бэкенда не запущен. Упавший сервер приложения, остановленный пул PHP-FPM, контейнер, который завершился или провалил проверку здоровья. Прокси подключается к порту, на котором никто не слушает.
  • Бэкенд упал посреди запроса. Убийство из-за нехватки памяти или ошибка сегментации закрывает соединение до того, как завершились заголовки ответа.
  • Неверный адрес или порт вышестоящего сервера. Конфигурация, указывающая на старый порт после изменения, либо на хост, который больше не разрешается.
  • Несовпадение протокола. Прокси говорит обычным HTTP с портом, ожидающим TLS, или наоборот. Байты неразбираемы, поэтому прокси называет ответ невалидным.
  • Слишком большие заголовки ответа. Слишком большая cookie или необычно длинный заголовок превышают буфер прокси, и ответ отклоняется, а не передается дальше.
  • Несовпадение keep-alive. Прокси переиспользует простаивающее соединение, которое бэкенд уже закрыл, что дает спорадические 502 при в остальном нормальной нагрузке.
  • Перезапуски и деплои. Любое окно, когда старый процесс уже остановился, а новый еще не принимает соединения.
  • Все бэкенды нездоровы. Балансировщику нагрузки без единого проходящего проверку участника некуда отправить запрос.

Чтение лога прокси, которое обычно и завершает расследование

Код состояния общий, а строка лога прокси - конкретная. Для nginx стоит узнавать такие сообщения:

[error] connect() failed (111: Connection refused) while connecting to upstream,
        upstream: "http://127.0.0.1:8080/"

[error] upstream prematurely closed connection while reading response header
        from upstream

[error] recv() failed (104: Connection reset by peer) while reading response
        header from upstream

[error] upstream sent too big header while reading response header from upstream

[error] no live upstreams while connecting to upstream

Каждое указывает на свое:

  • connect() failed (111: Connection refused). На этом адресе и порту никто не слушает. Бэкенд остановлен, привязан к другому интерфейсу либо находится на другом порту, чем указано в конфигурации.
  • upstream prematurely closed connection. Бэкенд принял запрос, а затем упал или повис, не завершив ответ. Ищите падения, убийства из-за нехватки памяти или таймаут воркера внутри приложения, а не в nginx.
  • connection reset by peer. Похоже, но соединение было активно сброшено. Часто это файрвол посередине либо бэкенд, закрывший пуловое соединение, которое прокси все еще считал открытым.
  • upstream sent too big header. Проблема размера буфера в прокси, а не сбой в бэкенде. Ответ валиден, но больше, чем настроен вмещать прокси.
  • no live upstreams. Проверки здоровья пометили каждый бэкенд как недоступный.

Как это исправить

  1. Проверьте бэкенд напрямую, в обход прокси. С хоста прокси запросите сам вышестоящий адрес:
    curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/
    200 здесь при 502 на публичном URL означает, что проблема в конфигурации прокси либо в связи между ними двумя. Отклоненное соединение означает, что бэкенд действительно лежит.
  2. Проверьте, что бэкенд запущен и слушает на адресе, который ожидает прокси. Привязка к 127.0.0.1, когда прокси обращается к адресу контейнера, - частая причина.
  3. Прочитайте лог ошибок прокси и сопоставьте сообщение со списком выше, прежде чем менять какую-либо конфигурацию.
  4. Затем прочитайте лог бэкенда. Падение, убийство из-за нехватки памяти или таймаут воркера в ту же секунду подтверждает случай "prematurely closed". Тишина указывает обратно на проблему соединения.
  5. Проверьте адрес, порт и схему вышестоящего сервера в конфигурации прокси, особенно после миграции или пересборки контейнера.
  6. Увеличьте буферы заголовков прокси, если лог говорит, что заголовок был слишком большим, и отдельно выясните, почему заголовок разросся.
  7. Сделайте так, чтобы деплои перекрывались. Запустите новый процесс, дождитесь, пока он пройдет проверку здоровья, затем слейте трафик со старого и остановите его. Скользящие обновления с проверкой здоровья полностью убирают окно перезапуска, вызывающее 502 во время деплоя.

Как поймать 502, длящийся двадцать секунд

502 во время деплоя и в цикле падений короткие. Бэкенд перезапускается, отдает ошибки двадцать секунд и восстанавливается, так что к моменту, когда кто-то проверяет, сайт уже в порядке, и смотреть уже не на что. Плановая HTTP-проверка, работающая непрерывно, фиксирует эти окна с метками времени, что превращает "утром было что-то странное недолго" в паттерн, который можно сопоставить с деплоями и перезапусками. 502 также может приходить от граничного узла CDN, а не от вашего источника, поэтому проверка из нескольких регионов отличает глобальный сбой бэкенда от проблемы на границе, затрагивающей часть вашего трафика, а для этого и нужен распределенный мониторинг доступности.

Проверить сейчас

Запустите бесплатную проверку своего сайта - аккаунт не нужен.

HTTP check

Следить за этим постоянно

Получайте оповещение в момент сбоя: HostTracker проверяет более чем из 300 локаций и уведомляет по email, SMS, в Slack, Telegram и не только.

Возможности HostTracker

Ещё в этом разделе: Коды состояния HTTP: разбор