TLS・QUIC・HTTP/3 — 詰まりをほどく新世代

同じページを開くのに、なぜ新しいプロトコルが必要なのか。鍵は「詰まり(ヘッドオブラインブロッキング)」と「往復(RTT)」という2つのムダです。HTTP/1.1の直列、HTTP/2の多重化とTCPの限界、そしてUDPの上に独立ストリームを作ったQUIC(HTTP/3)へ。1つの遅延・1つの欠落が誰を止めるのかを、流れるパケットで見比べます。TLSの中身を前提にします。

1. 直列の詰まり — HTTP/1.1

HTTP/1.1では、1本のコネクションは要求を1つずつ順番に処理します。前の応答が返るまで次に進めないので、途中の1つが重いと、後ろの要求がまとめて待たされます。これが要求レベルのヘッドオブラインブロッキングです(ブラウザは接続を6本ほど並べてごまかしますが、1本の中では直列のまま)。

下のデモでR2の重さを上げると、R3・R4の完了がどれだけ後ろへずれるか見てください。

HTTP/1.1 — 1本の接続は要求を順番に処理
横軸=時間。4つの要求 R1〜R4 が1本の接続で直列に処理されます。赤い縦線が現在時刻。R2を重くすると、後続のR3・R4の開始と完了がそのぶん丸ごと後ろにずれます。1つの遅れが全体を押し下げる、これが直列の弱点です。
POINT — 「詰まり」は2つの階層で起きる ここで見たのは要求(アプリ)レベルの詰まり。HTTP/1.1が抱える問題で、HTTP/2の多重化が解きます。ところがもう一段下、TCP(トランスポート)レベルにも別の詰まりが潜んでいて、そちらはHTTP/2でも残ります。次の節でその正体を見ます。

2. 多重化 — HTTP/2 が1本に混ぜて流す

HTTP/2は、複数のリクエスト/レスポンスを小さなフレームに刻み、1本のTCP接続に混ぜて(多重化して)同時に流します。もう順番待ちの列は要りません。すべてのストリームが最初から並行して進むので、最初のデータがどれも早く届きます。

下のデモで1.1と2を切り替えて、3つのリソースの進み方の違いを見てください。

多重化 — HTTP/1.1(直列)と HTTP/2(並行)
3つのリソース A・B・C を1本の接続で受け取ります。HTTP/1.1ではA→B→Cと順番に埋まり、Cが始まるのはずっと後。HTTP/2では3本が同時に進み、どれも最初のデータがすぐ届く(=ページの描画が早く始められる)。総量が同じでも「届き始めの速さ」が変わります。

3. TCPの壁とQUIC — 1個の欠落は誰を止めるか

HTTP/2の多重化には落とし穴があります。土台のTCPは順序を保証するため、1個のセグメントが失われると、その後ろに届いたデータは全ストリーム分まとめて待たされます。多重化したのに、パケット1個で全員が止まる — これがTCPレベルのヘッドオブラインブロッキングです。

QUICはこれを、UDPの上に独立したストリームを自前で作ることで解きます。あるストリームのパケットが欠けても、止まるのはそのストリームだけ。下のデモで方式を切り替え、パケットを落として誰が止まるか確かめてください。

パケットロス — HTTP/2(TCP)と QUIC(UDP)
3本のストリームがパケットを送っています。HTTP/2は1本のTCPを共有するので、共通の順序ゲートが閉じると全ストリームが停止。QUICはストリームごとに別々のゲートを持つので、欠落したそのストリームだけが待ち、他は流れ続けます。「落とす」を押して見比べてください(欠落は決定的に再現されます)。
注意 — HTTP/2は「TCPの詰まり」を受け継いでいた HTTP/2は要求レベルの詰まりを解きましたが、TCPの順序保証に由来する詰まりは残りました。回線品質が悪い(ロスが多い)ほどこの影響は大きくなります。QUICはトランスポートをUDP+自前の再送・順序管理に置き換え、暗号化(TLS 1.3相当)まで統合してこの壁を越えました。HTTP/3はそのQUICの上で動くHTTPです。なお、通信の盗聴・改ざんの実験は自分の管理下の機器だけで。自分のシステム以外への攻撃・盗聴は犯罪です。

4. ハンドシェイクの往復 — 速く安全につなぐ

安全な通信を始めるには、鍵の合意と相手の確認が要ります。その往復(RTT)が少ないほど、最初の1バイトが早く届きます。TLS 1.2はTCPの1往復+TLSの2往復で計3往復。TLS 1.3はTLS部分を1往復に短縮。QUICは接続確立と暗号化を統合して1往復、再接続時は0-RTTで最初のパケットに暗号化データを同送できます。

下のデモで方式を選び、往復遅延を変えてください。遠い相手(遅延が大きい)ほど、往復を減らす効果が効いてきます。

ハンドシェイクの往復数 — TLS 1.2 / 1.3 / QUIC
上=選んだ方式のメッセージの流れ(クライアント⇄サーバ)。下のバー=各方式のデータ送信までの時間 = 往復数 × 往復遅延。遅延を上げると、往復の多いTLS1.2ほどバーが伸び、QUIC・0-RTTの優位がはっきりします。
最初のデータまでの時間 ≈ 往復数(RTT) × 往復遅延 TLS1.2 ≈ 3-RTT、TLS1.3 ≈ 2-RTT、QUIC ≈ 1-RTT、QUIC 0-RTT ≈ 追加往復ゼロ。遅延の大きい遠距離ほど差が効く

5. まとめ — 詰まりと往復を、両方けずる

一歩先へ — 0-RTTの代償と、接続の「持ち運び」 QUICの0-RTTは速い一方、初回データが再送攻撃(リプレイ)に弱いため、副作用のない操作に限る等の注意が要ります(安全に使うための制約であって、攻撃手法の話ではありません)。またQUICは接続をコネクションIDで識別するので、Wi-Fiからモバイル回線へ切り替えてIPが変わっても接続が途切れません(コネクションマイグレーション)。TCPには真似のできない芸当です。ネットワーク編はこのあとCDNと負荷分散へ — 速く届ける工夫は、プロトコルの外側にも広がっていきます。