この記事は「渡部 Advent Calendar 2025」の14日目の記事です。
システムの耐障害性を考えるとき、真っ先に思い浮かぶのは冗長化やオートスケール、リトライ、サーキットブレーカーかもしれません。 しかし、それらの土台には必ずネットワークプロトコルがあります。TCPなのか、UDPなのか。HTTPなのか、WebSocketなのか。ステートレスなのか、ステートフルなのか。これらの選択は、障害が起きたときの「壊れ方」を大きく左右します。
この記事では、ネットワークプロトコルの性質が耐障害性にどのような影響を与えるのかを、実運用の視点から整理してみます。
プロトコルは「失敗の前提」を内包している
ネットワークは信頼できません。これは古典的ですが、今も変わらない事実です。
- パケットは落ちる
- 遅延はばらつく
- 接続は突然切れる
- 相手はいつの間にか死んでいる
優れたネットワークプロトコルは、これらを前提として設計されています。
TCP の思想
- 順序保証
- 再送制御
- フロー制御
- コネクション管理
その代わりに、
- 接続確立コストがある
- ヘッドオブラインブロッキングが起きうる
- 状態(state)を持つ
という性質を受け入れています。
TCP を使っている時点で、私たちは「途中で壊れても最終的には届く」という世界観を選んでいます。この辺の詳細はこの記事で書くのは大変なので以下のような書籍とかを参照してみてください。
ステートフル通信は障害に弱い(が、価値がある)
WebSocket や長時間の TCP 接続は、耐障害性の観点では扱いが難しい存在です。
- コネクションが切れると文脈が失われる
- 再接続時の状態復元が必要
- 負荷集中時に一斉切断が起きやすい
一方で、リアルタイム性や低レイテンシが求められるシステムでは避けられません。
ステートフルであることのコスト
ステートフルな通信を選ぶということは、「障害時に、どこまでを自動で回復させるか」をアプリケーション側が引き受ける、という意味になります。
- 再接続時の再送は誰がやるのか
- 途中状態は破棄してよいのか
- 二重実行は許されるのか
ここを曖昧にしたままスケールさせると、障害時に必ず破綻します。
HTTP が「強い」のはステートレスだから
HTTP/1.1 や HTTP/2、HTTP/3 が耐障害性の面で優れている理由の一つは、基本的にステートレスであることです。
- 1 リクエスト = 1 意味
- 接続が切れても再試行できる
- 冪等性を設計に組み込みやすい
ロードバランサ、プロキシ、CDN が強力なのも、この性質のおかげです。
冪等性はプロトコルだけでは守れない
ただし、HTTP を使っていれば自動的に安全になるわけではありません。
- POST を何度も投げたらどうなるか
- タイムアウト後にサーバ側で処理は続いているか
- クライアントはそれをどう扱うか
プロトコルは「再送できる余地」を与えてくれるだけで、意味的な安全性(Exactly Once)はアプリケーションの責任です。
具体的にどういったリトライをすると良いんだっけは前に発表したスライドがあったりするのでみてもらえると嬉しいです。
タイムアウトは「失敗の境界線」
耐障害性の設計で最も重要なのが、タイムアウトです。
ネットワークプロトコルは、相手が本当に死んだのか、単に遅いのかを教えてくれません。だからこそ、
- クライアントは一定時間で諦める
- サーバは途中キャンセルを考慮する
- 冪等性が必要になる
という連鎖が生まれます。
「壊れ方」を理解して設計する
耐障害性を高めるとは、「障害をなくす」ことではありません。
- どう壊れるのか
- 壊れたときにどこまで守るのか
- 人はどこで介入するのか
これをプロトコルの性質から逆算することが重要です。
- TCP 接続が切れたら、何が失われるか
- 再送されたリクエストは安全か
- 並行処理中に順序が崩れても問題ないか
ネットワークプロトコルは抽象的な存在ですが、耐障害性は極めて具体的で、現場的な問題です。
おわりに
信頼性の議論は、つい「仕組み」や「ツール」に寄りがちです。しかし、その根底には必ずネットワークプロトコルがあります。
- プロトコルは思想である
- 思想は失敗の扱い方に現れる
- 失敗の扱い方が耐障害性を決める
どのプロトコルを選ぶかは、どんな障害を許容し、どんな障害を拒否するかの選択です。
次に設計をするときは、「このプロトコルは、障害時にどんな顔をするのか?」を一度考えてみると、見える景色が変わって面白いかもしれません。