マイ備忘録

あくまで個人の意見、メモです。

ALBと配下のproxy(nginx)のkeepalive timeoutについて

Client <--> ALB <--> proxy(nginx) <--> App の構成でkeepalive timeoutをどう設定するのか...

ALBで設定できる項目

idle_timeout.timeout_seconds

ターゲットとのkeepaliveのtimeout。デフォルトは60秒。

client_keep_alive.seconds

クライアントとのkeepaliveのtimeout。デフォルトは3600秒。

docs.aws.amazon.com

ALB、nginxの設定内容

以下が推奨設定

repost.aws

キープアライブ (Apache の KeepAlive、NGINX の keepalive_disable)

CPU 使用率を削減し、応答時間を改善するには、キープアライブをオンにします。キープアライブをオンにすると、ロードバランサーで、HTTP リクエストの度に新しい TCP 接続を確立する必要がありません

キープアライブタイムアウト (Apache の KeepAliveTimeout、NGINX の keepalive_timeout)

キープアライブオプションが有効になっている場合は、ロードバランサーのアイドルタイムアウトよりも長いキープアライブタイムアウトを選択します。

読み取りタイムアウト (Apache の RequestReadTimeout、NGINX の client_header_timeout と client_body_timeout)

アプリケーションの応答時間に合わせて読み取りタイムアウトを設定します。こうすることで、ロードバランサーがリクエストのヘッダーとボディの両方を受信するために、接続を十分な時間開いたままにしておくことができます。

とのこと。

nginxはkeepalive_timeoutを0に設定すると無効になる(リクエスト毎にTCPのコネクションをcloseする)。 何も設定していなければデフォルトの60秒になるため、keepaliveはもちろん有効である。

nginx.org

キープアライブオプションが有効になっている場合は、ロードバランサーのアイドルタイムアウトよりも長いキープアライブタイムアウトを選択します。

nginxのkeepalive_timeoutが60秒であれば、idle_timeout.timeout_secondsはそれより短い値が推奨値となる。

読み取りタイムアウト (Apache の RequestReadTimeout、NGINX の client_header_timeout と client_body_timeout)

client_header_timeoutとclient_body_timeoutはnginxのクライアント(ここではALB)からのリクエストに対する設定となる。

client_header_timeout

nginx.org

If a client does not transmit the entire header within this time, the request is terminated with the 408 (Request Time-out) error.

とのこと。ALB -> nginxのリクエストのヘッダにそんな大きなものはないので、デフォルトの60秒でよいだろう。

client_body_timeout

nginx.org

If a client does not transmit anything within this time, the request is terminated with the 408 (Request Time-out) error.

とのこと。ALB -> nginxでデフォルトの60秒以内になにも送らないということは現状発生していないので、デフォルトのままにしておく。

ALBのclient_keep_alive.secondsは、ロードバランサーがリクエストのヘッダーとボディの両方を受信するために、接続を十分な時間開いたままにしておくことができます。 とのことなので、デフォルトの3600秒は十分に長い。特に問題も起きていないのでこのままにしておく。

TCP keepaliveとHTTP keepalive

参考

milestone-of-se.nesuke.com

kazuhira-r.hatenablog.com

TCP keepalive

TCP keepaliveは以下に定義してある

datatracker.ietf.org

  • コネクションがアイドル状態になってから一定時間が立つとkeepalive probe(ペイロードが空のACKのリクエスト)を送る
  • keepalive probeを受け取ったらACKで応答する
  • ペイロードに1オクテット(バイト)のデータを入れても良い(空だと送れないものもある)
  • probeの応答がなくなったらRSTを送ってコネクションを切断する

HTTP keepalive

developer.mozilla.org

コネクションが確立している状態であれば、3-wayハンドシェイクなしでHTTPのリクエストをTCPセグメントで送るようにする機能。 その際に Connection: keep-alive のヘッダが付与される。 この Connection: keep-alive ヘッダがあれば、新しいコネクションではなく、すでに確立しているコネクションを使うようにサーバ側が対応する。 明示的にコネクションを切断する場合、Connection: closeヘッダを付与してリクエストを出すとTCPのコネクションが切断するように処理される。

HTTP/2では1つのTCPのコネクション内で複数のリクエスト・レスポンスを送る(Multiplexing)ので、HTTP keepaliveというものは存在しない(デフォルトでコネクションを維持する設計になっている)。