ELBのメトリクスのステータスには、バックエンドのEC2が返したステータス(HTTPCode_Backend_XXX)と、ELB自身のステータス(HTTPCode_ELB_5XX)があります。
ELB自身のステータスコードの中には504というエラーコードがあります。この504エラーと格闘した話を書きます。
この504エラーは、CloudWatchのメトリクスで言うとHTTPCode_ELB_5XXに上がってきます。
このメトリクスは5XXという名前の通り、504以外のコードも含んでいます。
例えば、
HTTP 502: Bad Gateway
(バックエンドサーバからのレスポンスがHTTPレスポンスとして解釈不能)や、HTTP 503: Service Unavailable
(突発的なアクセス増によりスケールが間に合わない時など)
などがあります。
実際に504かどうかはS3に保存されたアクセスログを見ると確認することができます。
他のエラーも発生することはあり、それぞれトラブルシュートしたことはあるのですが、どれも上記のリンクの説明読んだり、調査したり、AWSサポートと連携したりで問題無く原因特定できました。しかし、 HTTP 504: Gateway Timeout
は全く原因がわからない。
HTTP 504: Gateway Timeoutとは
では HTTP 504: Gateway Timeout
とはどんなステータスなのでしょう。
Timeoutという名前の通り何かがタイムアウトした際に出るエラーです。具体的には、ELBからEC2にリクエストを投げて返ってくるまでの時間(Backend Processing Time)が、ELBのアイドルタイムアウトに設定した値を超えると発生します。
実際に、ELBのアイドルタイムアウトをデフォルトの60秒だとして、60秒以上Sleepする処理をELB経由でEC2側で動かせばエラーを再現できます。
504が散発した
ここまで書いているように、ELBで運用していたら時に504が 散発
しました。
時々日に100件などの単位で大量に発生する場合もありますが、それなら逆に原因はELB自体にある可能性が高いです。AWSサポートに頼めば、ELBノードを交換してもらえる時もあります。。
問題は、低頻度(週に2〜3件とか)の単位で発生する504エラーです。それ以外のリクエストは正常で何も問題無く見える場合です。
- バックエンド処理が重いということは無く、小さな静的ファイルを返すだけでも発生する場合がある
- アクセス数と発生数は比例しない(アクセス数が高くても低くても発生する)
- EC2側のApacheやNginxは正常に応答しているように見える
詳細な調査をするためにtcpdumpなど使うにも、週に数件、出るか出ないかわからないもののためにELB配下のサーバ全てでtcpdump使うのは厳しいです。
なかなか調査が進みません。
原因
AWSの方々とも何度も何度もやりとりしたのですが、結局原因わからずです。
ELBのノードを交換してもらったり、EC2側も色々チューニングしたり、Apacheのバージョン換えたり設定変えたり、Nginxにしてみたり、カーネルチューニングしてみたり、かなり頑張ったのですが何も効果無かったです。
AWS ELB配下のApache Http Server推奨設定のAWS公式情報 - YOMON8.NET
対策
対策は題名の通りです。ALBにしたら全く発生しなくなりました。
気持ちとしては釈然としないのですが、ブラックボックスのELB側を見れない以上調査も難しく時間かかるので、同じ事象に遭遇している人がいれば、まずはALBにしてみるのも手かと思います。運用整備する工数の方が恐らく小さくなるのではと思います。