私の経験上、「ELBがおかしいぞ!AWSしっかりしろや!」と思ったら、よくよく調べると実装がダメなだけだったというパターンがよくあるのでまとめたい。
あ、ELBと言いながら厳密にはALBの話をメインにします。
CASE 1. 「バックエンドは生きてるはずなのにヘルスチェックが失敗する!」
つまり以下のような症状が出る状況
- ヘルスチェックが失敗する
- バックエンドに直接アクセスしたら普通にうまくいく
- バックエンドのアクセスログ見たら、ヘルスチェックに200を返している
というパターン。
「バックエンドは生きてるしヘルスチェックにも200を返してる!それなのに失敗扱いなんてELBの不具合だ!」と思いたくなる気持ちはわかるが、まずは落ち着いてヘルスチエックの成否の基準を見直そう。
・ターゲットグループのヘルスチェック - Elastic Load Balancing
ターゲットが応答タイムアウト期間内に応答するのを待ちます。
つまりバックエンドが200を返していようが、タイムアウトしていたらヘルスチェック的には失敗なのだ。
とりあえずバックエンドのアクセスログから処理時間を確認してみよう。まさか処理時間を出力するようにログフォーマットを設定してないなんて言わないよな?
ちなみにステータスコード200というのも注意が必要で、みんな大好きApacheのドキュメントにこんな記載がある
・mod_log_config - Apache HTTP サーバ バージョン 2.4
| %s | ステータス。内部でリダイレクトされたリクエストは、元々の リクエストのステータス --- 最後のステータスは %>s |
|:--|:--|
すこぶる分かりにくい文章だが、要するに
・ %s -> リダイレクトが発生した際に3XXのコードを出力する
・ %>s -> リダイレクトが発生した際に3XXのコードを出力せず、リダイレクト後の処理の結果のコードを出力する
というわけだ。そのため、「200を返してるし、CPU使用率も上がってないから大丈夫なはず」と思ってたら実はリダイレクトしまくってタイムアウトしてた、というパターンもある。
そして、筆者の記憶が確かならApacheではデフォルトで%>sが設定されている。
というわけでこの症状の場合は、ELBの不具合とヘルスチェックのタイムアウト、どちらの方がありえそうか考えて調査をはじめてみよう。
CASE 2. 「HTTPCode_ELB_5XX_Countメトリクスが出てる!」
「5XXはサーバサイドのエラー…ELBが5XXエラーを出しているということは…ELBの不具合や!」と思いたくなる気持ちはわかるが、まあ落ち着いてほしい。
私も過去に502 Bad Gatewayに悩まされ、AWSにも問い合わせたりしたが、結局のところバックエンドの実装がクソだったのが原因だった。
だから落ち着いてまずはこれを見てほしい。
・Application Load Balancer のトラブルシューティング - Elastic Load Balancing
うん、分かりにくいな。
5XX系のエラーに絞って、頑張って解説してみよう。
HTTP 502: Bad Gateway
そもそも502 Bad Gatewayというもの自体が分かりにくい。
Wikipediaによると
不正なゲートウェイ。ゲートウェイ・プロキシサーバは不正な要求を受け取り、これを拒否した。
これで理解できる人間はほぼいないだろう。
502 Bad Gatewayについてはこちらのページの解説が分かりやすい。
・502Bad Getewayの原因と意味について | ぷろめし|プログラミングよりも飯が好き
ELBに当てはめて考えるなら、「ELBからバックエンドにリクエストを投げたが、解せないレスポンスが帰ってきた」という状況である。
つまり、ELBがイかれている可能性もあるが、バックエンドがイかれたレスポンスを返したり途中でコネクションをブッチしている可能性もあるのだ。
つまり、502 Bad Gatewayが現れたらバックエンドからのレスポンスがどうなってるかを見直した方がいいだろう。
HTTP 503: Service Unavailable
一時的に使えないというやつ。
上記のドキュメントにはターゲットグループにインスタンスが無いという場合しか書いてないが、実は他にも503が発生する可能性はある。
ELBはトラフィック量に合わせて自動でスケールするが、あまりに急激にトラフィックが増加した場合にはスケールが間に合わなくなることがある。そういう場合にはELBの処理能力が足りなくなって503が発生することになる。
ほっといたらそのうちELBがスケールして解決するが、「一瞬たりとも落とせないんだ!」という時は予めPre-warmingを申し込んでおこう。
・Elastic Load Balancing の暖気申請について | Developers.IO
見積もりがガバガバだと「ほんまにPre-warming必要か?」と突っ込まれることもあるので、真面目に見積もろう。
HTTP 504: Gateway Timeout
これは分かりやすい。
ELB -> バックエンドの通信がタイムアウトしたということである。
バックエンドの処理を見直すか、タイムアウト時間を伸ばすかの二択だが、基本的にはバックエンドの処理を見直す方が健全である。
色々調べたが、どう考えても実装に問題はない時は…
AWS側の問題という可能性もあるので、問い合わせよう。