9
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

はじめに

SENSYN Robotics(センシンロボティクス)の中山です。
Webアプリやそのインフラ周りと、Web側とドローンの接続を行うデバイスドライバ的な部分を担当しています。

今回はAzure Application GatewayでHTTPの502 Bad Gatewayが出たときの話です。

Azure Application Gateway

Microsoft Azureで提供されている、HTTP・HTTPSのレイヤー7ロードバランサです。AppGWと略すことが多いです。AWSのApplication Load Balancer(ALB)みたいなものですね。マネージドサービスなので、管理が楽です。

ロードバランサなので、ユーザーに公開されるIPアドレスはAppGWのものになります。SENSYN RoboticsのサービスはKubernetes上のコンテナとして動いているのですが、そのコンテナ群のフロントエンドとして機能します。

図にするとこんな感じ↓。

Web browser <--HTTPS--> AppGW <--HTTP--> containers on Kubernetes

502 Bad Gateway

サービスの提供を開始した頃、いくつかのリクエストに対して502 Bad Gatewayが返るという問題が発生しました。テストしてみると、大量1のリクエストを送ったときに発生するようです。

当初は、コンテナ側の負荷上昇が原因でAcceptキュー(backlog)が溜まり、時間内にHTTP接続を受け付けられなかったことで接続タイムアウトしたのだと考えていました。

しかし、tcpdumpで調査してみると、そもそもTCPの接続要求(SYN)が来ていないように見えます。AppGWが502を返すまでの時間が非常に短いことからも、backlog溢れによる接続タイムアウトという可能性は低そうでした。

HTTP1.1

AppGWのドキュメントを見てみると、バックエンドとHTTP1.1で通信するとあります。

HTTP2 のサポートより

バックエンド サーバー プールへの通信は、HTTP/1.1 で行われます。

HTTP1.0とHTTP1.1の違いといえば、

A. 接続の再利用
B. パイプライン
C. Chunked response
D. キャッシュ制御の標準化

といった辺りです。今回は接続で問題が起きているので、Aの接続の再利用が関係している可能性が高そうです

仮説

HTTP1.1で追加された機能である接続の再利用をAppGWが利用している2とすると、以下のシーケンスで問題が起きそうです。

  1. AppGWがリクエストを受け付ける
  2. AppGWがバックエンドに対してTCP接続する
  3. TCP接続を通してHTTPのリクエストをバックエンドに投げる
  4. バックエンドがAppGWにレスポンスを返す
  5. AppGWがクライアントにレスポンスを返す
  6. AppGWはTCP接続を切らない
  7. バックエンドは一定時間使われていないTCP接続を切断しようとする
  8. 切断中にAppGWがリクエストを受け付ける
  9. AppGWが切断中のTCP接続にリクエストを送ろうとする
  10. 送れないのでBad Gatewayエラーを返す

AppGWはまだ接続中だと思っているTCP接続が、バックエンド側では切断されている、という状況です。バックエンド側で切るのが早すぎるのが問題です。

解決

バックエンド側が一定時間使われていないと判断する閾値を変更しました。具体的にはKeep-Aliveのタイムアウトを5秒から3分にしています。

問題の起きていたバックエンドはNode.jsで書かれているので、以下のようなコードにしました。

var server = http.createServer(app).setTimeout(config.timeout.server());
server.keepAliveTimeout = config.timeout.server();  // デフォルトは5秒

この修正を入れてテストしてみると、きれいに502エラーが消えました。問題解決です。

まとめ

  • Azure Application Gatewayで502 Bad Gatewayが起きたときは、バックエンド側のKeep-Aliveが原因のケースがある
  • tcpdumpを使うと原因を切り分けやすい
  1. 大量といっても100req/s程度

  2. connection poolingの一種と考えられます

9
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?