HTTPQUERY
English

504 Gateway Timeout

用法

504 Gateway Timeout 状态码表示服务器正作为上游服务器的代理或网关。在收到 HTTP 请求后,服务器尝试将请求转发给上游服务器,但在允许的时间内未收到任何响应。

这与 502 Bad Gateway 状态码相关。502 表示上游服务器返回了无效的响应,而 504 表示根本没有收到任何响应。

平台特定的超时各不相同。Shopify API 强制执行 10 秒的请求超时,当响应未在此时间窗口内就绪时返回 504 Gateway Timeout。使用 Shopify API 的开发者对于超过此限制的操作,必须优化查询并使用后台处理。

SEO 影响

Googlebot 将 5xx 错误视为暂时降低整个站点抓取速率的信号。已被索引的 URL 起初会被保留,但长时间的停机会导致 Google 将它们从索引中剔除。任何随 504 响应返回的内容都会被忽略。Google 在其文档中明确将 500、502 和 503 归为服务器错误一类。504 属于同一大类的 5xx 错误。robots.txt 文件上的 5xx 错误要严重得多,即便站点上其他每个页面都返回 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 时,ProxyPassMatch 指令上的 timeout 参数控制等待时间。

对齐后端超时。后端进程需要与之匹配或更高的超时时间。对于 PHP,提高 php.ini 中的 max_execution_time 以及 PHP-FPM 进程池配置中的 request_terminate_timeout。对于 Node.js,设置 server.timeout。对于 Gunicorn,使用 —timeout。

优化缓慢的后端操作。超时是操作缓慢的一种症状。对请求进行性能剖析以找出瓶颈:

尊重平台施加的超时。托管平台强制执行的硬性限制比典型的代理默认值更短。Shopify 施加 10 秒的上限。对于超过平台限制的操作,将工作卸载到后台任务,并轮询结果,而不是阻塞 HTTP 请求。

检查网络路径。使用 curl 或 telnet 验证代理与后端之间的连通性。丢包、DNS 延迟或中间跳点上的防火墙规则都会导致超时。运行 traceroute 以识别缓慢的网络段。

添加缓存。对于幂等请求,在代理层缓存响应可避免反复调用缓慢的后端。Nginx 的 proxy_cache_path 和 Apache 的 mod_cache 都能降低上游负载。

代码参考

.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