はじめに
- 私は現在AWS上のWEBシステムのインフラ維持管理を担当しています
- システムのタイムアウト設計は地味な領域ではありますが、設計に不備があるとシステム障害に直結する、非常に重要なポイントの一つだと考えています
- 一方で、直近の業務を通じてこの領域は専門外の方には理解しづらいものであるものの、アプリケーション担当者の方々にも内容を把握していただくことが不可欠だと改めて実感しました。そこで、この機会に自身の知見を整理する意味も込めて、本記事へまとめることにしました
該当条件(主に本投稿を確認頂きたい方)
- タイムアウト設計未経験で、設計のポイントを確認したい方
- タイムアウト設計ポイントは把握しているが、なぜそのような設定にする必要があるのかを確認したい方
- TCP/IPを前提としたOSI参照モデルの考え方やTCP/IPの通信処理フローなど基礎的なネットワーク知識の説明は本記事では省略しています
導入・前提知識の整理
1. タイムアウト設定の目的
「クライアント側」と「サーバ側」の双方が、主に以下の目的で設定を行います。また、それぞれが適切にタイムアウトを設定することで、一方の障害や遅延が対向側へ波及し、システム全体に悪影響が及ぶことを防ぎます。
| 項目 | 設定目的 | イメージ例 |
|---|---|---|
| クライアント | サーバへの無駄な接続試行・待ちの回避 | ・ネットワークの不具合やサーバがダウンしている場合に永久に待たされることを防止する |
| サーバ | サーバリソースの保護、クライアントへのサービス維持 | ・サーバー側で処理を実行するのに許容する最大時間を制限し、他リクエスト処理に影響が出ないようにする/使われていないクライアントのコネクションを切断する |
- TCP/IPの仕様上、コネクションの確立は必ずクライアントから行われますが、コネクションの終了(破棄)については、クライアントとサーバのどちらからでも行うことが認められています。
- したがって、タイムアウトを契機としてクライアント側からコネクションを切断する動作も、仕様に則った正当な挙動であると言えます。
2. 「コネクション」「トランザクション」「セッション」の違い
- それぞれの違いを以下に表形式でまとめます
| 項目 | 概要 |
|---|---|
| コネクション | HTTPリクエストなどアプリケーション間で通信を行うための伝送経路 |
| トランザクション | コネクションが張られている前提で行われるオンライン画面上の検索処理や更新処理など一連の処理 |
| セッション | コネクションが確立後、切断されるまでに行われる複数トランザクションを含む一連の処理 |
3. 「TCP Keep-Alive」と「HTTP Keep-Alive」の違い
- 「TCP Keep-Alive」と「HTTP Keep-Alive」は、動作するレイヤーや目的が異なります。以下にその違いをまとめます
| 項目 | TCP Keep-Alive | HTTP Keep-Alive |
|---|---|---|
| レイヤー | トランスポート層(L4) | アプリケーション層(L7) |
| 目的 | TCP接続が生きているか確認(死活監視) | HTTP接続の再利用 パフォーマンス向上 |
| 動作タイミング | 一定時間無通信時に自動的にプローブ送信 | HTTPリクエスト/レスポンス完了後に接続を維持 |
| 設定場所 | OS・カーネルレベル | アプリケーション・Webサーバレベル |
| 送信データ | 空のACKパケット(データなし) | HTTPヘッダー(Connection: keep-alive) |
| 主な用途 | ・ファイアウォール等のタイムアウト防止 ・切断の早期検知 ・ゾンビコネクション除去 |
・複数HTTPリクエストでの接続再利用 ・3-wayハンドシェイクの省略 ・レイテンシ削減 |
| HTTPヘッダ | なし |
Connection: keep-aliveKeep-Alive: timeout=5, max=100
|
| 切断契機 | プローブ応答がない場合 | タイムアウト、maxリクエスト到達、Connection: close受信時 |
| オーバーヘッド | 極小(定期的な空パケット) | 小(接続確立の削減効果) |
| 無効化の影響 | 切断検知が遅れる | リクエスト毎に接続確立が必要 |
- 図の例ではクライアント側からTCP Keep-Aliveの確認を開始する図としていますが、サーバ側のTCP Keep-Alive開始タイミングの方が設定上短い場合は、サーバ側から開始する場合もあります
- 図の例ではクライアント側からTCPコネクションクローズを開始する図としていますが、サーバ側のHTTP Keep-Alive開始タイミングの方が設定上短い場合は、サーバ側からTCPコネクションクローズを開始します
- 具体的なパケットなどの処理イメージは以下サイトに詳しく書かれておりましたのでこちらを参考に確認ください
【補足】
上述の通り、「TCP Keep-Alive」と「HTTP Keep-Alive」では動作するレイヤーが異なります。
そのため、仮に「HTTP Keep-Alive」の有効期間中に、サーバ側で「TCP Keep-Alive」のプローブパケットを受信したとしても、「HTTP Keep-Alive」側のタイマーはリセットされない点に注意してください。
これは、プローブパケットにアプリケーションレイヤー(HTTP)のデータが含まれていないためです。
4. タイムアウト設定箇所
- タイムアウト値は、先述した「コネクション」「トランザクション」「セッション」の各レイヤーごとに設定が存在します。以降、各項目における設定箇所の例を表にまとめます。
| 項目 | 特徴 | 対象項目例 | 説明 |
| コネクションタイムアウト | 接続や通信に対する待ち時間 | Connection Timeout | サーバに接続要求を送ってから、接続完了の応答が返ってくるまでの待ち時間。接続に失敗した場合、このタイマーで即座にエラーとし、無駄な待ち時間を避ける |
| IdleTimeout | 接続が確立した後、次のリクエストが来ないアイドル状態を維持する最大時間。この時間を超えると、中間NW機器(ロードバランサ/ファイアウォール等)はコネクションを強制的に切断する | ||
| HTTP Keep-AliveTimeout | HTTPリクエスト送信時に確立したTCPコネクションを維持し流用し続ける時間。この時間を超えると、サーバはコネクションを切断し、次のリクエストから再接続する | ||
| ReadTimeout/SocketTimeout | コネクション確立後、コネクション経由でデータが返ってくるまでの待ち時間。この時間を超えるとクライアントはサーバの処理完了を待たずにエラーとする | ||
| トランザクションタイムアウト | 業務処理・DB処理など「各処理」に対する時間制限 | Statement Timeout | SQLクエリ実行の最大許容時間。この時間を超えるとSQLの実行を強制終了する |
| Transaction Timeout | DB操作を含む業務処理全体を完了させるための最大許容時間。この時間を超えるとサーバは処理を中断し、データベースのロールバックなどを実行しリソースを開放する | ||
| セッションタイムアウト | ログイン状態を保持に対する時間制限 | SessionTimeout | ユーザがシステムに接続した状態(ステート)を保持する最大期間。この時間を超えるとサーバはそのセッション情報を破棄する(クライアント側は再度認証処理が求められるようになる) |
システム全体のタイムアウト設計を行う上では、各コンポーネントで設定可能なタイムアウト値が「どのレイヤーの、どのような制御に対する設定なのか」を正しく把握することが非常に重要です。
タイムアウト設計のセオリー
1.TCP(L4レイヤ)
- TCPコネクションは確立された後、以下の点を除き原則として接続を維持するように設計されています(ただし、ファイアウォールやロードバランサーといった中間ネットワーク機器による切断を除きます)
- →先ほどの電話通話の話を例にすると、「スマホの電話アプリ(アプリケーションL7レイヤ))」を利用し通話中の状態にて「通話終了」ボタンを操作する前に、「通信キャリア側(TCP:L4レイヤ)」で「長電話を検知したので通話を終了しました」と勝手に通信が切られると皆さん困ると思います。そのようなイメージです。
- ①上位レイヤ(アプリケーション)からのコネクション切断指示(L7レイヤで制御)
- ②無効なコネクションの検知・破棄(L4レイヤで制御)
- →先ほどの電話通話の話を例にすると、「スマホの電話アプリ(アプリケーションL7レイヤ))」を利用し通話中の状態にて「通話終了」ボタンを操作する前に、「通信キャリア側(TCP:L4レイヤ)」で「長電話を検知したので通話を終了しました」と勝手に通信が切られると皆さん困ると思います。そのようなイメージです。
- 本項では、上記に示す項目のうち、L4レイヤーの役割である「②無効なコネクションの検知・破棄(TCP Keep-Alive)」と、中間ネットワーク機器で設定される「TCP Idle Timeout」について整理します
(1)TCP IdleTimeout設計
- ファイアウォールやロードバランサーといった中間ネットワーク機器は、内部的にセッション情報を管理し、通信を監視しながら動作します。一方で、リソース管理の観点から「TCP Idle Timeout」のタイマー設計が行われており、無通信状態が続いたコネクションは不要と判断され、管理テーブルからの削除およびコネクションの強制切断が行われます
- したがって、これらの機器で設定される「TCP Idle Timeout」の設定値は、後述するアプリケーションレイヤー側のコネクションおよびトランザクションタイマーの設計ポリシーに合わせて検討する必要があります
(2)TCP Keep-Alive設計
- TCP Keep-Aliveの動作概要は、前述の3. 「TCP Keep-Alive」と「HTTP Keep-Alive」の違いで記載した通りですが、この処理は「TCP Idle Timeout設計」で触れたタイマーをリセットする上でも、重要な役割を果たします
- 具体的には、ファイアウォールやロードバランサーといった中間ネットワーク機器の「TCP Idle Timeout」よりも短い間隔で、TCP Keep-Aliveのプローブパケットが送信されるように設計します。これにより、意図せずTCPコネクションが切断(無効化)されることを防ぐことができます
- Linuxディストリビューションのデフォルト値は「7200秒(2時間)」と設定されていることが多いですが、現代のパブリッククラウド利用などの観点からは、この機能を有効活用するために、より短い設定値(数分程度)にチューニングすることが望ましいです。ただし、具体的な設定値は、アプリケーションレイヤーや中間ネットワーク機器の設定を十分に考慮して決定する必要があります
2. アプリケーション(L7レイヤ)
(1)コネクション/トランザクション タイマー設計
-
アプリケーションレイヤのタイマー設計は「フロント側から徐々にタイムアウト値は小さくする」のが基本的な考え方です。なぜこのような設計にする必要があるのか、その理由を以下に記載します
-
ただし「HTTP Keep-Alive」は任意のTCPコネクションで「送信元のHTTP Keep-Aliveタイマー < 送信先のHTTP Keep-Aliveタイマー の大小関係をつけること」が基本的な考え方になります、具体的には先に記載した「TCP IdleTimeout」の設定も含めてまとめると以下の表・図の通りです

| 接続形態 | 対象コネクション | 設定大小関係 |
| クライアント⇔サーバ | クライアント⇔サーバ | クライアントのHTTPKeepAliveタイマー < サーバのHTTPKeepAliveタイマー |
| クライアント⇔ロードバランサ⇔サーバ | クライアント⇔ロードバランサ | クライアントのHTTPKeepAliveタイマー < ロードバランサのHTTPKeepAliveタイマー ≦ ロードバランサのTCP IdleTimeout タイマー |
| ロードバランサ⇔サーバ | ロードバランサのTCP IdleTimeout タイマー ≦ ロードバランサのHTTPKeepAliveタイマー < サーバ側のHTTPKeepAliveタイマー |
なぜそのような設計とすべきなのか例も含めて以下に記載します
-
下図の通り、送信元であるロードバランサがHTTP Keep-Aliveによって既存コネクションが有効と判断し利用しようした際に、送信先であるWEBサーバ側ではタイムアウトにより該当コネクションを切断していたことにより通信エラーが発生してしまいます(サーバ側のコネクションクローズとALBのHTTPリクエストが同時に行われた場合に発生)
(悪い例:WEBサーバのHTTP Keep-Aliveタイマ値がロードバランサより小さい値となっている場合)

-
そのため送信先でのHTTP Keep-Aliveのタイムアウトを防ぐため、「クライアント⇔ロードバランサ」と「ロードバランサ⇔サーバ」といったコネクションの区間毎に、先に記載した通りタイマー値は扇の形になるように(先に行くほど値を大きくする(範囲を広げる))することが必要です。(以下は扇型で設計した場合のタイムアウトを検知した場合の処理の例)

【補足】
- ALBで設定可能なTCPアイドルタイムアウト/HTTP Keep-Aliveタイムアウトの設定可能なパラメータを以下にまとめる
- バックエンド側のHTTP Keep-Aliveタイムアウト値は以下観点から実質「アイドルタイムアウト」と同値になる点について注意すること
- ALBの現状の仕様では設定した「アイドルタイムアウト」の設定値がバックエンド側にも強制適用される
- 結果、バックエンド側でHTTP Keep-Aliveタイムアウトを伸ばしたとしても「アイドルタイムアウト」が優先され、タイムアウト発生時はコネクションを切断する動きとなるため
| 対象コネクション | 設定対象パラメータ | 対象パラメータ設定項目名 | チューニング可否 | 説明 |
| HTTP クライアント ⇔ ALB 間(フロントエンド) | TCPアイドルタイムアウト | アイドルタイムアウト | △ | L4レイヤ(TCPIdleTimeout)、デフォルト60 秒。 1~4000 秒の範囲で設定可。ただしバックエンド側も共通の設定値として適用される |
| HTTP Keep-Aliveタイムアウト | HTTP クライアントのキープアライブ期間 | 〇 | デフォルト3600 秒。60~604800秒(7日間)の範囲で設定可 | |
| ALB ⇔ バックエンドターゲット 間(バックエンド) | TCPアイドルタイムアウト | アイドルタイムアウト | △ | フロントエンド側も共通の設定値として適用される |
| HTTP Keep-Aliveタイムアウト | HTTP クライアントのキープアライブ期間 | △ | 「アイドルタイムアウト」の設定値が自動的に適用される。 |
(2)セッション タイマー設計
- まずセッションタイムアウトが発生した場合、一般的にどのような挙動となるのか(どのように設計するのか)を以下に整理します
- ①サーバ側で該当のセッション情報を内部的に無効化(期限切れ)扱いとする ※この時点では特に何も通信は発生しない
- ②クライアントが次のHTTPリクエストを送信する
- →サーバ側は該当リクエスト受信後、セッション管理情報と突き合わせを行い、該当リクエストのセッションは無効だと処理する
- ③該当のリクエストは「システムエラー」扱いとせず、例えば以下のような処理をクライアントに促す
- 302応答を返したうえで、ログイン画面にリダイレクトさせる 等
- 該当リクエストで行っていた業務処理は処理状況に応じてロールバックなどを行い、業務上問題ない状態にする
【参考】
- あくまでセッション情報だけのタイムアウト処理のため、仮にHTTP Keep-Alive有効期間中にセッションタイムアウトが発生した場合も、既存TCPコネクションを流用し動作します(コネクションエラーなどは発生しない)
- 上記整理から前述のコネクション/トランザクションタイムアウト値とは切り離して考えることができるが、セッションタイムアウト値が短い場合、高頻度で認証処理を行わなければならなくなるため、実用性と業務特性を鑑みて設定する(WEBオンラインシステムであれば、一般的には数十分~1h程度で設定)
まとめ
本記事では、Webシステムにおけるタイムアウト設計の重要性と、具体的な設計セオリーについて解説しました。設計時に意識すべきポイントを以下にまとめます。
- L4とL7の役割を区別する: TCP Keep-Aliveは中間機器のIdleTimeoutより短く設定し、予期せぬ切断を防ぐ。
- トランザクションは「漏斗型」: 前段(クライアント側)の待ち時間を後段より長く設定し、処理完了前のタイムアウトを避ける
- HTTP Keep-Aliveは「扇型」: 後段(サーバ側)の有効期間を前段より長く設定し、再利用時の通信エラーを防止する
- セッションは業務特性で判断: 認証維持の利便性とセキュリティのバランスを考慮する。
タイムアウト設計は「なんとなくデフォルト値」で済ませてしまいがちですが、一つひとつの設定がシステムの安定稼働に直結します。本記事が、インフラ・アプリ両担当者の円滑な設計・連携の一助となれば幸いです。






