HTTPQUERY
日本語

503 Service Unavailable

使い方

503 Service Unavailable ステータスコードは、一時的な理由によりサーバーが HTTP リクエストを実行できないことを意味します。トラフィックの急増でサーバーが過負荷になっている、リソースがロックされている、サーバーが再起動中である、あるいはファイアウォールの設定ミスがリクエストをブロックしている、といった状況です。

多くのサイトはサイトのメンテナンス中に 503 Service Unavailable ステータスコードを返します。これは検索順位に影響が及ばないようにするための推奨されるアプローチです。

ロックされたリソースや過負荷のリソースなど、サーバーが問題を把握している場合、Retry-After の HTTP ヘッダーがリクエストを再送信すべき時期をクライアントに伝えます。

Amazon S3 は、リクエストレートがプレフィックス単位のスループット制限を超えると 503 Slow Down を返します。これらのしきい値を超える急激な増加は、S3 がバックグラウンドでパーティションをスケールするあいだスロットリングを引き起こします。オブジェクトを複数のプレフィックスに分散させ、指数バックオフを実装し、リクエストレートを徐々に引き上げることでこのエラーを回避できます。S3 は 503 レスポンスに課金しません。

Fastly は、リクエストが同じ Fastly サービスへ戻るようにルーティングされていると見られる場合や、Fastly のサーバーを通過しすぎた場合に、「Loop detected」という理由テキストとともに 503 Service Unavailable を返します。Fastly は Fastly-FF ヘッダーと CDN-Loop ヘッダーを使ってリクエストのホップを追跡します。次のいずれかの制限を超えると、リクエストはループとして拒否されます。同一サービスについて同じ POP への事前の訪問が3回を超える、リクエスト経路上で一意の Fastly サービスが6個を超える、全サービスを通じた合計ホップ数が20を超える、のいずれかです。ループは、同じホスト名がサービスのドメインとバックエンドの両方として設定され、そのホスト名の 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