# AWS 504 Gateway Timeout エラー完全解決ガイド

AWS Elastic Beanstalk で重たい処理を実行した際に、504 Gateway Timeout エラーが発生しました。CloudWatch のメトリクスではHTTPCode_ELB_5XXに記録されます。

本記事では、504 エラーの原因と解決方法を詳しく解説します。

# HTTP 500 系エラーの種類

HTTP 500 系のエラーには、以下のような種類があります。

コード サーバーステータス説明
500 Internal Server Error サーバーエラー
501 Not Implemented リクエスト不能
502 Bad Gateway レスポンス不能
503 Service Unavailable リクエスト処理できない
504 Gateway Timeout 時間タイムアウト
505 HTTP Version Not Supported HTTP バージョンサポートなし
506 Variant Also Negotiates ネゴシエーションエンドポイントエラー
507 Insufficient Storage サーバー容量不足
508 Loop Detected ループ入ってます
510 Not Extended 拡張サポートなし
511 Network Authentication Required 認証エラー

502-504 エラーが一般的でよく見られます。プログラムスペルミスなどでよく 503 起こります。507 エラーはたまにサーバーの容量不足で起こります。何年かに一回出て、長年会ってない親戚みたいな気持ちになります。

# 504 エラーの原因調査

今回の AWS 504 timeout エラーの原因として、以下の 4 つを調査しました。

項目 結果 備考
プログラムソース 問題なし 普段は正常に動作し、重たい処理の時だけ発生するため、プログラムの可能性は低い
CloudFront 該当なし CloudFront は使用していない
サーバー設定 要確認 Apache のタイムアウト設定が原因の可能性
ロードバランサー 要確認 ELB のアイドルタイムアウト設定が原因の可能性

調査のポイント

普段は正常に動作し、重たい処理の時だけエラーが発生する場合は、タイムアウト設定が原因である可能性が高いです。

# 解決方法 1:Apache サーバー設定の変更

Apache のタイムアウト設定を変更することで、504 エラーを解決できる場合があります。

# 推奨設定値

設定項目 説明
Timeout 300 リクエストのタイムアウト時間(秒)
KeepAliveTimeout 300 KeepAlive 接続のタイムアウト時間(秒)
KeepAlive On KeepAlive 接続を有効化
MaxKeepAliveRequests 10000 1 つの接続で処理する最大リクエスト数
AcceptFilter http none HTTP の AcceptFilter を無効化
AcceptFilter https none HTTPS の AcceptFilter を無効化

# 設定ファイルの場所

Linux の場合:

/etc/apache2/apache2.conf

Windows XAMPP の場合:

xampp/apache/conf/original/extra/httpd-default.conf
#
# Timeout: The number of seconds before receives and sends time out.
#
Timeout 300

#
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
#
KeepAlive On

#
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
#
MaxKeepAliveRequests 10000

#
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
#
KeepAliveTimeout 300

# AWS ELB 用 Apache 推奨設定

AWS ELB(Elastic Load Balancer)を使用している場合の推奨設定は以下の通りです。

設定項目 説明
Timeout 120 ELB のアイドルタイムアウト(デフォルト 60 秒)より大きい値に設定
KeepAlive On CPU 使用率を削減し、応答時間を改善
KeepAliveTimeout 120 Timeout と同じか、それより長い値を設定
MaxKeepAliveRequests 100 単一の TCP 接続で処理するリクエスト数を 100 以上に設定
LogFormat "%{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"" X-Forwarded-For ヘッダーを含むログフォーマット
AcceptFilter http none ロードバランサー使用時は無効化
AcceptFilter https none ロードバランサー使用時は無効化

設定のポイント

  • Timeout: ELB のアイドルタイムアウトよりも大きな値に設定する必要があります
  • KeepAlive: CPU 使用率を削減し、応答時間を改善します
  • KeepAliveTimeout: Timeout と同じか、それより長い値を選択します
  • MaxKeepAliveRequests: 単一の TCP 接続で処理するリクエストの数を 100 以上に設定します
  • AcceptFilter: ロードバランサー使用時は、TCP ソケットを「ハーフオープン」状態にするためnoneに設定します

# 解決方法 2:ロードバランサーのアイドルタイムアウト設定変更

# CloudWatch メトリクスで確認

CloudWatch メトリクスを確認し、HTTPCode_ELB_5XXメトリクスにデータポイントが存在する場合、時間内に処理が完了しなかったため、ロードバランサーのアイドルタイムアウトで引っかかった可能性があります。

# 解決方法の選択

以下の 2 つの方法があります。

  1. アイドルタイムアウト値を変更(コストなし)
  2. インスタンスの計算能力を上げる(コストあり)

推奨アプローチ

まずはアイドルタイムアウト値を変更してみて、それでも解決しない場合はインスタンスのスケールアップを検討します。

# ロードバランサーのタイムアウト設定変更手順

  1. Amazon EC2 (opens new window)コンソールを開く
  2. サイドメニュー[LOAD BALANCING] -> [ロードバランサー]を選択
  3. 対象のロードバランサーを選択
  4. [Description]タブ -> [Edit idle timeout]を選択
  5. [Configure Connection Settings] -> [Idle timeout]の値を1 - 4000 秒に変更
  6. [Save]を選択

注意

  • デフォルトのアイドルタイムアウトは60 秒です
  • 最大値は4000 秒(約 66 分)です
  • タイムアウト値を長くしすぎると、リソースの無駄遣いになる可能性があります

# 実装時の注意点

AWS 504 Gateway Timeout エラーの解決方法。

  1. Apache サーバー設定の変更

    • Timeout、KeepAliveTimeout を適切な値に設定
    • ELB 使用時は、アイドルタイムアウトより大きい値に設定
  2. ロードバランサーのアイドルタイムアウト設定変更

    • CloudWatch で HTTPCode_ELB_5XX を確認
    • 必要に応じてアイドルタイムアウト値を延長(最大 4000 秒)
  3. インスタンスのスケールアップ(最終手段)

    • 処理時間を短縮するため、インスタンスタイプを変更

トラブルシューティングの順序

  1. CloudWatch メトリクスでエラーを確認
  2. Apache 設定を確認・変更
  3. ロードバランサーのタイムアウト設定を変更
  4. それでも解決しない場合は、インスタンスのスケールアップを検討

関連情報: AWS ELB アイドルタイムアウト設定 (opens new window)

同じタグを持つ記事をピックアップしました。