こんにちは!クラウドの世界へようこそ。SREとして日々システムの裏側を支えていると、ユーザーからの「なんだか画面が真っ白になって、エラーが出るんです!」という悲鳴のような問い合わせに直面することがよくあります。
その中でも、Webアプリのインフラを触るようになったエンジニアの前に、ある日突然立ちはだかる「ラスボス」のような存在があります。そう、それがHTTPステータスコードの「502 Bad Gateway」です。
今回は、AWSの顔とも言えるロードバランサー(ALB: Application Load Balancer)の世界で、この502エラーがなぜ起きてしまうのか、その裏側でパケットやサーバーたちがどんなドラマ(あるいは悲劇)を繰り広げているのかを、身近な例えを交えながら一歩ずつ優しく紐解いていきましょう!
—
502 Bad Gatewayって、そもそもどんな状態?
「502 Bad Gateway」をひとことで言うと、「中継地点(郵便局の窓口)が、奥の部屋(倉庫)からおかしな荷物を受け取ったか、そもそも奥の部屋と連絡が取れなくなって困ってしまい、お客さんに『ダメだこりゃ』と伝えている状態」です。
インターネットの世界でこれを当てはめてみると:
- お客さん(クライアント):スマホやPCでWebサイトを見ているあなた
- ALB(Application Load Balancer):ビルの総合受付や郵便局の窓口(リクエストを受け取って、後ろのサーバーに振り分ける)
- ターゲット(EC2やECSなどのバックエンドサーバー):実際に裏でプログラムを動かしてページを作っている倉庫のスタッフ
お客さんから「このページをちょうだい!」と頼まれたALBは、後ろにいるターゲット(サーバー)に「ねえ、このページを作ってよ」と仕事を振ります。しかし、その返事が「なんだこれ?意味わかんないよ」という壊れた返事だったり、サーバー自身がプツンと連絡を断ってしまったりしたとき、ALBは困り果ててお客さんに502 Bad Gatewayを返すのです。
—
ALBで502エラーが起きる「よくある3つの理由」
現場のトラブルシューティングで最も遭遇する、代表的な3つの原因を見ていきましょう。一歩ずつ理解していけば、怖くありませんよ!
1. ターゲット(バックエンド)からのレスポンスが「壊れている」
ALBは非常に几帳面な受付係です。インターネットのルール(HTTPの仕様)に厳格で、ターゲットから返ってきた返事の形が少しでも変だと、「おや、これは受け取れないぞ」と跳ね返してしまいます。
- ありがちなケース:HTTPのヘッダー部分に使えるはずのない文字が入っていたり、レスポンスの形式がルール違反だったりする場合。
2. ターゲットが勝手にTCPコネクションを切断した
お店で注文をした直後に、店員さんが「あ、休憩行ってきまーす」と急にいなくなったら困りますよね? それと同じ現象がサーバーの裏側で起きています。
- ありがちなケース:バックエンドのアプリ(例えばNode.jsやPython、PHPなど)のタイムアウト設定が、ALBの設定よりも短く作られている場合。ALBが「まだ話の途中だよ!」と待っているのに、サーバー側が「もう限界、切るね!」と一方的に通信の回線(TCPコネクション)を切ってしまうと、ALBは
502を返さざるを得なくなります。
3. Keep-Aliveのミスマッチ(アイドルタイムアウトの罠)
ここが一番のハマりどころです!ALBとターゲットの間では、一度繋いだ通信回線を何度も使い回す「Keep-Alive」という仕組みが使われています。
もし、ALBのアイドルタイムアウト時間が60秒に設定されているのに、バックエンドのサーバー(例えば裏にいるNginxやApacheなど)のタイムアウトが5秒だったらどうなるでしょう?
サーバー側が「5秒間誰も話しかけてこないから、この回線は閉じちゃおう」と勝手に店じまいした直後に、ALBが「ねえ、新しい注文いい?」とその閉じられた回線めがけて話しかけてしまうと……。「おっと、回線が切れている!」ということで、502エラーが発生してしまうのです。
—
現場で役立つ!502エラーの具体的な調査手順
「実際に502が出てしまった!」という時、SREはどのように原因を突き止めているのでしょうか。現場のリアルなステップを覗いてみましょう。
Step 1: ALBのアクセスログを確認する
まずは、AWSのコンソールやS3に保存されているALBのアクセスログを覗いてみます。ここで重要なのが、エラーログに含まれる「ターゲットステータスコード(target_status_code)」と、「エルロコード(elb_status_code)」です。
- もしログの
elb_status_codeが502で、target_status_codeが-(ハイフン)または特定の変なコードになっている場合: - → ALB自身がリクエストをバックエンドにうまく渡せなかった、あるいはバックエンドから全く返事が返ってこなかったことを意味します。
Step 2: ターゲット(サーバー)のアプリログを見てみる
次に、バックエンドのサーバー(EC2やECSタスク)の中に入り、アプリケーションのエラーログ(Nginxのログや、アプリ特有のログファイル)を確認します。
例えば、Linux環境のNginxであれば、以下のコマンドでリアルタイムにエラーログを監視できます。
# Nginxのエラーログをリアルタイムで監視する実用コマンド
# 接続の切断や、アップストリーム(バックエンドアプリ)との通信エラーがないかチェックします
sudo tail -f /var/log/nginx/error.log
もしここで Aupstream timed out や Connection reset by peer のような文字が見つかったら、犯人は「サーバー側のタイムアウト設定やアプリのクラッシュ」に絞り込めます!
—
トラブルを未然に防ぐ!インフラ設定のベストプラクティス
最後に、こうした502エラーに二度と悩まされないための、実務で今すぐ使える設定のコツをご紹介します。
1. タイムアウトの「秒数ピラミッド」を正しく作る
一番大切なのは、「外側から内側に向かって、タイムアウト時間を少しずつ長くする」という鉄則です。
- クライアント ⇄ ALB のタイムアウト:例)60秒
- ALB ⇄ バックエンド(Nginx等) のタイムアウト:例)65秒
- Nginx ⇄ アプリケーション(GunicornやPHP-FPMなど) のタイムアウト:例)70秒
このように、外側の門番(ALB)ほど短く、内のスタッフ(アプリ)ほど長く構えておくことで、サーバーが勝手に先に店じまいしてしまう事故を防ぐことができます。
2. AWS CLIでALBのアイドルタイムアウトを確認・変更する
もしALB側のタイムアウト時間を調整したい場合は、AWS CLIを使ってサクッと確認・変更が可能です。
# 現在のALBの属性(タイムアウト値など)を確認するコマンド
aws elbv2 describe-load-balancer-attributes \
--load-balancer-arn arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:loadbalancer/app/my-alb/1234567890abcdef
# アイドルタイムアウトを「60秒」から「120秒」に変更するコマンド
aws elbv2 modify-load-balancer-attributes \
--load-balancer-arn arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:loadbalancer/app/my-alb/1234567890abcdef \
--attributes Key=idle_timeout.timeout_seconds,Value=120
—
まとめ
いかがでしたでしょうか?
「502 Bad Gateway」と聞くと何やら難しそうに見えますが、要するに「ALBという受付係と、裏で働くサーバーの息が合っていないよ」というサインに過ぎません。
仕組みを一つひとつ分解して、郵便配達やお店のスタッフに例えて考えてみると、どこを直せばいいのか(タイムアウト設定やアプリの健やかさ)がクリアに見えてきますよね。
インフラやネットワークの世界は、こうした「見えない通信のキャッチボール」の積み重ねです。エラーに出会ったときは、「おっ、システムが新しいヒントを教えてくれたぞ」と前向きに捉えて、一歩ずつ原因を紐解いていきましょう!
それでは、快適なクラウドライフを!
コメント