HTTPQUERY
English

503 Service Unavailable

用法

503 Service Unavailable 状态码表示服务器因某个暂时性原因而无法完成 HTTP 请求。可能是服务器因突发的流量激增而过载、资源被锁定、服务器正在重启,或防火墙配置错误正在阻挡请求。

许多站点在进行站点维护时返回 503 Service Unavailable 状态码,这是确保搜索排名不受影响的推荐做法。

当服务器知晓问题所在时,例如资源被锁定或过载,Retry-After HTTP 头会告知客户端何时重新提交请求。

当请求速率超过每前缀(per-prefix)吞吐量限制时,Amazon S3 会返回 503 Slow Down。超过这些阈值的突发峰值会在 S3 后台扩展分区期间触发限流。将对象分散到多个前缀、实现指数退避并逐步提升请求速率可以避免该错误。S3 不会对 503 响应收费。

当某个请求看起来又路由回同一个 Fastly 服务,或经过了过多的 Fastly 服务器时,Fastly 会返回带有原因文本 “Loop detected” 的 503 Service Unavailable。Fastly 使用 Fastly-FF 和 CDN-Loop 头跟踪请求跳数。当请求超过以下任一限制时会被判定为循环并拒绝:针对同一服务对同一 POP 的先前访问超过三次、请求路径中出现的唯一 Fastly 服务超过六个,或跨所有服务的总跳数超过二十。当同一主机名同时被配置为某服务的域名和后端,且该主机名的 DNS 解析到 Fastly 时,通常会出现循环。为后端使用单独的源站主机名(例如 origin.example.re)或 IP 地址可以避免循环。

注意

503 意味着服务器对所有客户端暂时不可用(过载、维护)。429 意味着某个特定客户端超出了其速率限制。对按客户端的限流使用 429,对服务器范围的不可用使用 503。

SEO 影响

Googlebot 将 5xx 错误视为暂时降低整个站点抓取速率的信号。已被索引的 URL 起初会被保留,但长时间的停机会导致 Google 将它们从索引中剔除。任何随 503 响应返回的内容都会被忽略。Google 对 500、502 和 503 一视同仁。尽管常见建议有相反的说法,但对于计划内维护,503 相比其他 5xx 状态码并无特殊优势。robots.txt 文件上的 5xx 错误要严重得多,即便站点上其他每个页面都返回 200。Google 会暂停抓取长达 12 小时,然后回退到缓存副本长达 30 天。如果错误持续,Google 会将该站点完全从索引中移除。Bingbot 会遵循 503 响应上的 Retry-After 来安排返回访问的时间。持续的 503 响应会阻止在 Bing 中被索引。

示例

客户端请求某个资源,服务器返回 503 Service Unavailable,因为该资源暂时不可用。Retry-After 头建议在 30 分钟后重新提交请求。

请求

GET /latest_quotes HTTP/1.1
Host: example.com

响应

HTTP/1.1 503 Service Unavailable
Content-Type: text/html; charset=UTF-8
Content-Length: 124
Retry-After: 1800

<html>
  <head>
    <title>Resource Busy</title>
  </head>
  <body>
    <p>Try again after 30 minutes.</p>
  </body>
</html>

如何修复

先判断该 503 是有意的(维护模式)还是意外的(过载、崩溃)。搭配 Retry-After 头的有意 503 无需调试,只需等待维护完成。

对于意外的 503 错误,检查以下常见原因:

服务器资源耗尽。在服务器上运行 top、htop 或 vmstat。CPU 或内存占用过高意味着服务器缺乏容量。在 Apache 中,当所有工作进程槽位都被占用时,错误日志会显示 “server reached MaxRequestWorkers setting”。在 Apache 配置中提高 MaxRequestWorkers(对于 prefork MPM 还需提高 ServerLimit)。在 nginx 中,提高 events 块中的 worker_connections。

应用进程池崩溃。PHP-FPM、Gunicorn 或类似的进程管理器在负载下退出,会使 Web 服务器没有可用于处理请求的后端。检查进程管理器日志,然后增大进程池大小(PHP-FPM 中的 pm.max_children,Gunicorn 中的 —workers)。

连接池耗尽。数据库或外部 API 连接池耗尽会迫使应用拒绝新请求。在应用配置中增大连接池大小,并确认连接在使用后被正确释放。

速率限制。当阈值被超过时,nginx 的 limit_req 和 limit_conn 模块会返回 503(或自定义状态)。检查 limit_req_zone 和 limit_conn_zone 指令。提高 burst 值或添加 nodelay 以吸收流量峰值。

负载均衡器健康检查失败。失败的健康检查会将服务器从轮转中摘除。在 AWS ALB/NLB 中,在控制台检查目标健康状态。在 nginx 的 upstream 块中,检查 max_fails 和 fail_timeout 设置。

部署触发的重启。实例过少的滚动部署会造成短暂的 503 窗口。提高最小健康实例数或使用蓝绿部署。

AWS S3 限流(503 Slow Down)。S3 会对超过每前缀请求速率限制的请求进行限流。使用随机化的键前缀(例如 hex-hash/original-key)将对象分散到多个前缀。实现从 1 秒起的指数退避。逐步提升请求速率,而不是发送突发流量。在正确配置的情况下,AWS SDK 会以退避方式自动重试 503 SlowDown 响应。

对于流量峰值,添加 CDN 或缓存层以卸载静态请求。设置对 503 速率的监控和告警,以便在完全宕机之前暴露资源约束。

代码参考

.NET

HttpStatusCode.ServiceUnavailable

Rust

http::StatusCode::SERVICE_UNAVAILABLE

Rails

:service_unavailable

Go

http.StatusServiceUnavailable

Symfony

Response::HTTP_SERVICE_UNAVAILABLE

Python3.5+

http.HTTPStatus.SERVICE_UNAVAILABLE

Java

java.net.HttpURLConnection.HTTP_UNAVAILABLE

Apache HttpComponents Core

org.apache.hc.core5.http.HttpStatus.SC_SERVICE_UNAVAILABLE

Angular

@angular/common/http/HttpStatusCode.ServiceUnavailable