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

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

504 Gateway Timeout: медленные бэкенды, таймауты и разница с 502 и 503

Ответ 504 Gateway Timeout означает, что прокси достучался до вашего бэкенда, подождал ответа и сдался раньше, чем ответ пришел. Ничего не упало и никто не отказал в запросе: что-то за прокси работает медленнее, чем прокси готов ждать.

О чем сообщает 504

RFC 9110 определяет 504 для сервера в роли шлюза или прокси, который не получил своевременного ответа от сервера выше по цепочке. Слово «своевременный» задается конфигурацией, а не спецификацией, поэтому 504 это всегда утверждение сразу о двух вещах: насколько медленным был бэкенд и какой лимит выставили прокси.

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

504 против 502 и 503

502 Bad Gateway503 Service Unavailable504 Gateway Timeout
Что произошлоБэкенд отдал некорректный ответ или закрыл соединениеСервер намеренно отказался от работыБэкенд принял работу и не ответил вовремя
Состояние бэкендаЛежит, падает или говорит не на том протоколеРаботает, но перегружен или на техработахРаботает и занят, все еще обрабатывает
Скорость ответаОбычно мгновенноОбычно мгновенноМедленно, приходит по границе таймаута
Типичная строка в журналеconnect() failed или upstream prematurely closed connectionПравило техработ или отсутствие живых апстримовupstream timed out (110: Connection timed out)
Retry-AfterОбычно нетЧасто есть и рекомендуетсяОбычно нет
Куда смотреть первым деломЗапущен ли процесс бэкенда?Емкость, флаги техработ, проверки здоровьяМедленные запросы и медленные зависимости

На практике 502 падает быстро, 503 вежливо отказывает, а 504 сначала заставляет ждать. Отдельное руководство по 502 и обзор семейства 5xx разбирают два других кода целиком.

Почему бэкенд слишком медленный

  • Медленные запросы к базе данных. Отсутствующий индекс, запрос, выросший вместе с данными, паттерн N+1 в цикле или борьба за блокировки при конкурентной нагрузке. Самая частая причина.
  • Медленные вызовы сторонних сервисов. Исходящий запрос к API без собственного таймаута наследует худший день удаленного сервиса и передает его вашим посетителям.
  • Холодный старт. Первый запрос после масштабирования, старта контейнера или простоя оплачивает инициализацию, установку соединений и прогрев кэша разом.
  • Действительно тяжелая работа внутри веб-запроса. Формирование отчетов, выгрузки, обработка изображений или массовый импорт в синхронном режиме рано или поздно превысят любой разумный таймаут.
  • Борьба за ресурсы. Насыщение процессора, нехватка памяти и своп замедляют каждый запрос, поэтому границу первыми пересекают самые медленные.
  • Слишком жесткие таймауты. Если адресу законно нужно больше времени, чем разрешает прокси, ошибка в конфигурации, а не в коде.
  • Проблемы сети между шагами. Потери пакетов или задержки разрешения имен для адреса апстрима добавляют время, которого не видно в замерах приложения.

Как разобрать и починить 504

  1. Измерьте время до ошибки. Задержка перед 504 обычно совпадает с настроенным таймаутом, и по ней видно, какой шаг ее выдал:
    curl -sS -o /dev/null -w "%{http_code} %{time_total}s\n" https://example.com/slow-page
    Ошибка 504 почти ровно на 60 секундах указывает на стандартный таймаут чтения у прокси. На 30 или 100 секундах она указывает на тот компонент, где выставлено это число, часто на CDN, а не на ваш собственный прокси.
  2. Выясните, один это адрес или все. Один медленный URL это проблема приложения. Медленно везде и сразу это насыщение ресурсов или отказавшая зависимость.
  3. Прочитайте журнал ошибок прокси. В nginx строка вполне однозначна:
    [error] upstream timed out (110: Connection timed out) while reading
            response header from upstream, upstream: "http://127.0.0.1:8080/"
    В ней названы апстрим и фаза, а это отделяет медленное соединение от медленного ответа.
  4. Замерьте бэкенд напрямую, мимо прокси. Если тот же запрос к источнику занимает 90 секунд, прокси говорит правду, и чинить надо приложение.
  5. Профилируйте медленный путь. Посмотрите журнал медленных запросов, затем трассировки приложения. Большинство ошибок 504 сводится к одному запросу или одному исходящему вызову.
  6. Устраните причину, а не таймаут. Добавьте индекс, закэшируйте дорогой результат или вынесите действительно долгую работу в фоновую задачу, которая отвечает сразу и сообщает о прогрессе отдельно.
  7. Поднимайте таймаут только там, где работа законно длинная, и поднимайте его согласованно на каждом шаге. Лимит CDN в 30 секунд обесценивает таймаут источника в 120 секунд.
  8. Ставьте таймауты на собственные исходящие вызовы, чтобы медленная зависимость падала быстро и с внятной ошибкой, а не занимала воркер, пока прокси не сдастся.

Время ответа как раннее предупреждение

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

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

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

HTTP check

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

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

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

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