ロードバランサーのタイマー値に係るトラブル事例
はじめに
多くのシステムでは、可用性や負荷分散のためにロードバランサー(LB)が利用されています。
その中でも、しばしば見落とされがちな設定項目の一つが タイムアウト値 です。
例えば、次のような経験はないでしょうか。
「タイムアウト値をデフォルトのまま運用していたところ、長時間処理を行うアプリケーションにおいて、応答が返る前にLBが接続を強制切断してしまった」
タイムアウト値が適切でない場合、以下のような問題が発生する可能性があります。
- 短すぎる場合:長時間処理の途中で切断され、アプリケーションが予期せぬエラーを返す
- 長すぎる場合:不要なセッションが保持され続け、LBやバックエンドサーバのリソース圧迫、スループット低下につながる
- セキュリティ面:不要セッションの存在が、不正アクセスリスクの増大を招くこともある
そのため、LBのタイムアウト値は、LBの仕様の把握(デフォルト値、タイムアウト時の動作)はもちろんのことアプリケーション特性や通信パターン、セキュリティ要件を踏まえて慎重に設計し、適切な値を設定する必要がある重要なパラメータと言えます。
本記事では、タイムアウト値の設定不備が原因で発生した実際のトラブル事例を紹介し、その原因分析と解決策を共有します。
本内容が、今後の設計や運用、また同様の事象のトラブルシューティングに役立ち、安定したシステム実現の一助となれば幸いです。
事例のネットワーク構成
事象は、図にある Amazon Web Services(AWS) 上の構成のシステムで発生しました。
- IPアドレスを固定して Application Load Balancer(ALB) を利用するため、ALBの前段に Network Load Balancer(NLB) を配置する構成としている。
- クライアントもターゲットサーバもEC2で構築されている。
- ターゲットサーバはWebサーバとして動作させるため、Apacheを使用してHTTP KeepAliveを有効にしている。
- HTTP KeepAlive保持時間はアプリケーションの要件に従って10分程度(約600秒)とする。

発生した事象
クライアントが初回アクセス後、しばらく経ってから再度アクセスするとアプリケーションが一度エラーとなり、その後アクセスすると成功するという事象でした。当然、再接続時にエラーとなるようなことは想定外の動作です。
Webサーバのアクセスログを確認しても何が起きたか判断がつかなかったため、クライアント側でパケットレベルでの確認を行ったところLBからTCPリセット(RST)が返却されていることが分かりました。

調査
- 初回アクセス後、しばらく経ってから再度アクセスすると失敗する
- 事象発生時にLBがTCPリセットを返却している
という状況から、LBのタイムアウト値に起因する事象の可能性が高いと考え、NLBとALBのアイドルタイムアウトの仕様を調査しました。
- NLB - ALB
ここで注目すべきはNLBの
既定では、クライアントとターゲットの間に 350 秒間トラフィックがない場合、接続は NLB フローテーブルから削除されます。接続が追跡されなくなった後にクライアントがトラフィックを送信しようとすると、NLB は TCP RST で応答し、新しい接続を確立する必要があることを通知します。
という仕様です。
この仕様をもとに、コネクションテーブルの遷移とLBの動作を整理しました。
特定した原因
NLBのアイドルタイムアウト時(350秒)に当該接続はNLBのコネクションテーブルから削除されますが、NLBはアイドルタイムアウト時に接続終了の処理(FINの送信)を行わない仕様のため、クライアントはコネクションテーブルを保持した状態となります。


その後NLBの後段のALBのアイドルタイムアウト(600秒)によってALBがFINの送信を行いますが、NLBは既に当該接続のコネクションを削除済みのため、クライアントまでFINが届きません。

この状態でしばらく経ってからクライアントがアクセスすると、NLBはコネクションテーブルに当該接続が登録されていないため、クライアントにRSTを返却します。

結果、全てのノードでコネクションテーブルがクリアされたため、最初の状態に戻り、アクセス可能な状態に戻ります。

実施した解決策
特定した原因に基づき、NLBのTCPアイドルタイムアウトをALBのTCPアイドルタイムアウトより大きくする対策(1,000秒)を実施しました。
結果、TCP接続が正常に終了するようになり、無事事象は解決されました。

ALBは接続終了の処理(FINの送信)を行い、Webサーバのコネクションテーブルも削除されます。NLBはクライアントにFINを転送し、NLBとクライアントのコネクションテーブルも削除されます。

コネクションテーブルが全てクリアされたため、最初の状態に戻り、3wayハンドシェイクを行ってアクセスし、成功します。NLBがRSTで応答するようなことはなくなります。

なお、ここでNLBのTCPアイドルタイムアウトを過度に長時間設定してしまうと(上限6,000秒)、NLBのフローテーブルが枯渇して新規接続を受け付けなくなる可能性があります。前述のとおり、適切な値に設定する必要があります。

参考
本事例では該当しませんでしたが、LBとバックエンドのサーバとのタイムアウト値の関係にも留意する必要があります。
例えばですが、本構成においてWebサーバがALBのTCPアイドルタイムアウトが短い場合、ALBがWebサーバにリクエストを送信すると同時にWebサーバから接続終了の処理が行われる可能性があります。その場合、ALBはクライアントにエラーコード(502 Bad Gateway)を送信してしまいます。

まとめ
本記事では、LBのタイムアウト値に起因したトラブルについて、その原因と解決策を紹介しました。
今回のポイント
-
NLBのアイドルタイムアウトが発生するとEnd-to-EndのTCP接続が正常終了しなくなるため、NLBのアイドルタイムアウトはALBやターゲットサーバのタイマー値よりも長くする必要がある。
-
ただし、NLBのアイドルタイムアウト値を長くし過ぎると、NLBのフローテーブルが枯渇して新規接続を受け付けなくなる可能性があるため、適切な値に設定することが望ましい。
-
ALBよりもターゲットサーバのアイドルタイムアウト値(※HTTP KeepAlive保持時間)を短くした場合、クライアントにエラーコード(502 Bad Gateway)を送信することが起こり得るため避けることが望ましい。
NLBのタイムアウト > ALBのアイドルタイムアウト NLBのタイムアウト > サーバのアイドルタイムアウト ALBのタイムアウト < サーバのアイドルタイムアウト
LBのタイムアウト値の設計は、LBの仕様だけでなくクライアントやサーバの仕様に加えてアプリケーションの要件も考慮して決定する必要があります。設計時に、要件と仕様を踏まえた上で、タイムアウト値の関係とコネクションテーブルの遷移を図示化することで事前に防ぐことができます。
また、同様のトラブルに遭遇された場合は、まずはクライアントやサーバも含めた一連のTCPハンドシェイクの流れを確認するようにしてください。
NTT DATA公式アカウントです。 技術を愛するNTT DATAの技術者が、気軽に楽しく発信していきます。 当社のサービスなどについてのお問い合わせは、 お問い合わせフォーム nttdata.com/jp/ja/contact-us/ へお願いします。