LB idle timeoutとアプリKeepAlive設計の落とし穴

  • URLをコピーしました!

ロードバランサ(LB)配下のシステムで、
「通信が突然切れる」「一定時間後にRSTが返る」「再接続が頻発する」
といった問題が発生する場合、LBのidle timeoutとアプリのKeepAlive設計不整合が原因であるケースが非常に多くあります。

本記事では、LB idle timeoutの仕組みから、よくある設計ミス、現場での切り分け方法、
“どう設計すれば事故らないか”まで実務目線で解説します。

目次

LB idle timeoutとは何か

LBの idle timeout とは、

  • TCP接続が確立された後
  • 一定時間データ転送が行われない場合

その接続を LBが自動的に切断するまでの待ち時間 です。

代表的な例:

  • AWS ALB:60秒(デフォルト)
  • AWS NLB:350秒(TCP idle timeout)
  • Azure Load Balancer:240秒

重要なのは、アプリ側が生きていてもLBは容赦なく切るという点です。

KeepAliveとは何か(アプリ側視点)

KeepAliveとは、既存のTCP接続を再利用する仕組みです。

  • HTTP Keep-Alive
  • DBコネクションプール
  • APIクライアントの常時接続

アプリ側は、

「接続はまだ生きているはず」

という前提で通信を行います。

しかし、LBが先に切っていると、 アプリが次にデータを送った瞬間に RST を受け取ります。

よくある落とし穴①:LB idle timeout < アプリKeepAlive

最も多い事故パターンです。

  • LB idle timeout:60秒
  • アプリKeepAlive:300秒

この状態では、

  1. 通信が60秒止まる
  2. LBが接続を切断
  3. アプリは気付かず接続再利用
  4. RSTを受信してエラー

結果として、

  • ランダムな通信エラー
  • 再試行ループ
  • ユーザー体感の不安定さ

が発生します。

よくある落とし穴②:LB側からのRSTをアプリ障害と誤認

ログ上では以下のように見えることがあります。

  • Broken pipe
  • Connection reset by peer
  • EOFException

このため、

「アプリが落ちている」
「Javaが不安定」
「ネットワーク障害」

と誤診されやすいのが特徴です。

実際には、LBが仕様通りidle timeoutで切っているだけというケースが非常に多いです。

切り分け手順①:RSTの送信元を特定する

まず、RSTがどこから来ているかを確認します。

tcpdump -nn tcp and tcp[tcpflags] & tcp-rst != 0

確認ポイント:

  • RSTの送信元IPがLBか
  • サーバ自身か
  • クライアント側か

LB IPからRSTが返っている場合、idle timeoutを強く疑います。

切り分け手順②:通信間隔と切断時間を測る

エラーが出るまでの時間が、

  • ほぼ一定(60秒、120秒、240秒など)

であれば、LB idle timeoutと一致している可能性が高いです。

切り分け手順③:KeepAlive設定の確認

代表的な確認例:

# Java(例)
-Dhttp.keepAlive=true

# Apache
KeepAlive On
KeepAliveTimeout 300

# Nginx
keepalive_timeout 300;

LB idle timeoutより長く設定されていないか確認します。

正しい設計①:LB idle timeout > アプリKeepAlive

基本原則はこれです。

  • LB idle timeout:300秒
  • アプリKeepAlive:120秒

必ずLB側の方を長くします。

正しい設計②:アプリ側で定期的に通信を流す

どうしてもKeepAliveを長くしたい場合は、

  • アプリレベルのPing
  • HTTP/2 keepalive frame

などで、idle状態を作らない設計にします。

正しい設計③:短命接続に割り切る

API通信などでは、

  • KeepAliveを使わない
  • 接続は都度確立

という設計も有効です。

LB idle timeoutを気にしなくて済む反面、 接続数・ポート消費には注意が必要です。

まとめ

LB idle timeoutとKeepAliveの不整合は、

  • 再現性が低い
  • ログが分かりにくい
  • アプリ障害に見える

という理由で、現場で非常にハマりやすいポイントです。

重要なのは、

LBとアプリを「別物」として設計しないこと

通信の主導権はLBが握っている、という前提で設計することが、 安定運用への近道です。

目次