37
13

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 1 year has passed since last update.

お題は不問!Qiita Engineer Festa 2023で記事投稿!

ELBアイドルタイムアウトを伸ばす場合に注意した事

Last updated at Posted at 2023-06-22

前置き

3月からSREとして働いている井之口です。
これまではバックエンドエンジニアとして働いていたのですが、ポジションも変わってインフラに関わる事も多くなりました。
今回はELBの設定を変更する機会があったので、その際に学んだ事をまとめようと思います。

構成

スクリーンショット 2023-06-22 11.17.42.png

  • NginxがRailsのプロキシサーバーとして立っていて、ELBから負荷分散されている一般的な構成です
  • ALBアイドルタイムアウトは60秒に設定されています
  • Nginxのkeepalive-timeoutは60秒に設定されています

簡単に用語について説明しておきます

ALBアイドルタイムアウト

  • ALBが接続先であるNginxへ向けたTCPコネクションを保持する時間

keepalive_timeout

  • NginxがALBへ向けたTCPコネクションを保持する時間の事

対応内容

ではなんらかの理由でALBアイドルタイムアウトを伸ばさなければいけなくなったとしましょう。
今回は120秒に伸ばしたいのでまずアイドルタイムアウトのみ伸ばしてみます。

  1. ALBのアイドルタイムアウトを伸ばす (120秒)
  2. Nginxのタイムアウトは60秒のまま

このようなイメージです

スクリーンショット 2023-06-22 11.58.28.png

実はこの設定は不十分でAWS公式でもELBの接続先にNginxやApacheを置く場合は、接続先のタイムアウトを伸ばす事が推奨されています。

ELBのバックエンドサーバーとしてApacheまたはNGINXを使用するための最適な設定を教えてください。

なぜ問題があるのか?

  1. 60秒を超える処理が実行された場合、ALBより先にNginxがタイムアウトをする事で、Nginx側からTCPコネクションが切断される
  2. ALB側からは、TCPコネクションが切断されたのを検知するには、keepaliveで一定周期で相手が生存しているか確認応答をするまで待つ必要がある
    参考
  3. 結果、切断の確認をする前に別リクエストがALB側から貼られているTCPコネクションを使ってしまうと、Nginx側は既にコネクションを切断しているので、504エラーになる。

上記の様な事が発生する可能性があるため、Nginxの設定も変更する必要がありそうです。
追加で設定を入れてみます

追加対応

  1. ALBのアイドルタイムアウトを伸ばす (120秒)
  2. Nginxのkeepalive_timeoutをALBのアイドルタイムアウト以上にする (240秒)
  3. Nginxの proxy_read_timeoutを伸ばす
  4. Nginxのclient_header_timeout client_body_timeoutを設定する
スクリーンショット 2023-02-04 2.01.59.png (155.0 kB)
  1. 120秒を超える処理が実行される時に、ALBがNginxより先にタイムアウトをする事で、ALB側からコネクションが切断される
  2. ALB側からコネクションを切った後にNginxがコネクションを切るので、新しくALBから入ってくるリクエストが、切断されているコネクションに流れてくる可能性がない。

これで安全にコネクションを切断できる様になりました。

他に設定したプロパティの意味

proxy_read_tmeout

  • Nginxがプロキシ先(Rails)に投げたリクエストをタイムアウトする時間
  • つまりクエリ等が原因で時間がかかっている場合は、この時間を伸ばさないと結局タイムアウトすることになる
    • この記事はあくまで暫定対応前提のため、非同期処理やクエリチューニングなど考えた方がより良いです

client_header_timeout

  • クライアント(今回はALB)がNginxに投げたheaderをNginxが読み込むまでの時間のタイムアウト時間

client_body_timeout

  • 上記のリクエストボディ版

疑問点

  • TCPコネクションが切断される時の挙動
    • TCPコネクションを切断する場合って、FIN -> ACKでやりとりをしてから切断すると思っていたので、その時点で切断された事検知できるんじゃないのかなと思った。この辺り詳しい方教えていただければ嬉しいです。

終わりに

SREになり、バックエンドの業務ではあまり意識しないレイヤーの知識もサービスの信頼性を高める必要だと実感しています。
まだまだ未熟者ですが、これからもサービスの信頼性を向上させるにはどうすれば良いか考えながら業務をしていこうと思っています

参考にした記事

37
13
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
37
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?