HTTPQUERY
Русский

504 Gateway Timeout

Применение

Код состояния 504 Gateway Timeout означает, что сервер выступает в роли прокси или шлюза для вышестоящего сервера. Получив HTTP-запрос, сервер попытался переслать его вышестоящему серверу, но не получил ответа в отведённое время.

Это связано с кодом состояния 502 Bad Gateway. Код 502 указывает, что вышестоящий сервер вернул недопустимый ответ, тогда как 504 указывает, что ответ не был получен вовсе.

Таймауты различаются в зависимости от платформы. API Shopify применяет таймаут запроса в 10 секунд и возвращает 504 Gateway Timeout, если ответ не готов в пределах этого окна. Разработчикам, работающим с API Shopify, необходимо оптимизировать запросы и использовать фоновую обработку для операций, превышающих этот лимит.

Влияние на SEO

Googlebot воспринимает ошибки 5xx как сигнал временно снизить скорость сканирования всего сайта. Ранее проиндексированные URL поначалу сохраняются, но длительная недоступность приводит к их удалению из индекса. Любое содержимое, возвращённое с ответом 504, игнорируется. В своей документации Google прямо объединяет 500, 502 и 503 в группу серверных ошибок. Код 504 относится к той же общей категории ошибок 5xx. Ошибка 5xx на файле robots.txt куда серьёзнее, даже если все остальные страницы сайта возвращают 200. Google приостанавливает сканирование на срок до 12 часов, затем до 30 дней опирается на кэшированную копию. Если ошибка сохраняется, Google полностью исключает сайт из индекса. Bingbot также расценивает ответы 5xx как сбои сканирования. Устойчивые ошибки 5xx препятствуют индексации в Bing.

Пример

Клиент запрашивает ресурс, и сервер отвечает кодом состояния 504 Gateway Timeout, поскольку вышестоящий сервер не вернул HTTP-ответ.

Запрос

GET /news HTTP/1.1
Host: example.com

Ответ

HTTP/1.1 504 Gateway Timeout
Content-Type: text/html; charset=UTF-8
Content-Length: 128

<html>
  <head>
    <title>Gateway Timeout</title>
  </head>
  <body>
    <p>The server is not responding.</p>
  </body>
</html>

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

Прокси не дождался ответа от бэкенда. Решение — либо увеличить таймаут, либо ускорить бэкенд.

Увеличьте таймауты прокси.

В nginx таймаут по умолчанию составляет 60 секунд. Увеличьте соответствующие директивы в блоке server или location:

В Apache задайте ProxyTimeout 300 в виртуальном хосте или в глобальной конфигурации. При использовании mod_proxy_fcgi временем ожидания управляет параметр timeout директивы ProxyPassMatch.

Согласуйте таймауты бэкенда. Процессу бэкенда нужен такой же или больший таймаут. Для PHP увеличьте max_execution_time в php.ini и request_terminate_timeout в конфигурации пула PHP-FPM. Для Node.js задайте server.timeout. Для Gunicorn используйте —timeout.

Оптимизируйте медленную операцию на бэкенде. Таймаут — симптом медленной операции. Профилируйте запрос, чтобы найти узкое место:

Учитывайте таймауты, навязанные платформой. Хостинговые платформы применяют жёсткие лимиты, более короткие, чем типовые значения по умолчанию у прокси. Shopify устанавливает потолок в 10 секунд. Для операций, превышающих платформенный лимит, выносите работу в фоновые задачи и опрашивайте результат вместо блокировки HTTP-запроса.

Проверьте сетевой маршрут. Убедитесь в наличии связности между прокси и бэкендом с помощью curl или telnet. Потери пакетов, задержки DNS или правила межсетевого экрана на промежуточных узлах — всё это способствует таймаутам. Запустите traceroute, чтобы выявить медленные сегменты сети.

Добавьте кэширование. Для идемпотентных запросов кэширование ответа на уровне прокси избавляет от повторных медленных вызовов бэкенда. И proxy_cache_path в nginx, и mod_cache в Apache снижают нагрузку на вышестоящий сервер.

Примеры кода

.NET

HttpStatusCode.GatewayTimeout

Rust

http::StatusCode::GATEWAY_TIMEOUT

Rails

:gateway_timeout

Go

http.StatusGatewayTimeout

Symfony

Response::HTTP_GATEWAY_TIMEOUT

Python3.5+

http.HTTPStatus.GATEWAY_TIMEOUT

Java

java.net.HttpURLConnection.HTTP_GATEWAY_TIMEOUT

Apache HttpComponents Core

org.apache.hc.core5.http.HttpStatus.SC_GATEWAY_TIMEOUT

Angular

@angular/common/http/HttpStatusCode.GatewayTimeout