HTTP/2 と HTTP/3 実際に変更されたこと(およびAPIが気にしているかどうか)
HTTP/3はTCPをUDP上のQUICに置き換えます。これは実際にAPIの遅延、CDNの動作、およびあなたがそれについて何かする必要があるかどうかについて意味します。
短い答え:CDNの後ろにある場合は、HTTP/3はすでに処理されていて、設定する必要はありません。自前でサーバーを運営している場合は、HTTP/2が95%のケースをカバーしており、HTTP/3は価値があるが緊急ではないアップグレードです。
ここに長い説明があります。なぜなら、違いのエンジニアリングは実際に興味深いものであり、それがどのプロトコルバージョンが重要であるかを判断する上で役立ちます。
HTTP/2が実際に解決したこと
HTTP/1.1には、HTTP/2が適切に解決した2つの問題がありました。
1ページをロードするのにTCP接続が非常に多い。 ブラウザは、並列でアセットを取得するために、1つのオリジンに対して6~8のTCP接続を開いていました。各接続にはセットアップのオーバヘッド(TCPハンドシェイク、TLS交渉)があり、これはスケールアップ時に無駄でした。HTTP/2はこれをマルチプレクシングに置き換えました:1つのTCP接続上で、複数のリクエスト/レスポンスストリームが並列で動作します。これにより、接続の操作が不要になります。
すべてのリクエストに冗長なヘッダー。 HTTP/1.1では、すべてのリクエストがフルヘッダーを送信していました—— User-Agent, Accept-Encoding, Authorization、何も変わっていない場合でも、前のリクエストとまったく同じ内容を送信しています。HTTP/2のHPACK圧縮は、クライアントとサーバー間で共有される検索テーブルを維持することで、ヘッダーを重複して送信するのを削減します。同じ Authorization: Bearer ... トークンを毎回送信するAPIでは、高トラフィックの状況下でこのオーバヘッドが有意に削減されます。
サーバープッシュは、クライアントが要求する前に必要なリソースを事前に送るという3つ目のメリットでしたが、実際にはうまく機能しなかった。Chromeは2022年にサポートを削除しました。これは廃止されたものと見なし、何も構築しないでください。
HTTP/2が解決できなかった問題
ここがしばしば無視される部分です:TCP上のマルチプレクシングにはハードな上限があります。TCPパケットが中間で失われた場合、TCPはそのパケットが再送および承認されるまで、すべての接続を一時停止します。すべての並列HTTP/2ストリーム——失われたパケットがどのストリームに属するかに関わらず——待機状態になります。これはTCPレベルのヘッド・オブ・ライン(HOL)ブロッキングであり、HTTP/2のバグではありません。これはTCPが仕様として持つものです。
信頼できるワイヤド接続では、パケット損失率が低いので、これはほとんど影響しません。しかし、モバイルネットワーク、衛星リンク、またはパケット損失が意味のあるパスでは、HTTP/2のマルチプレクシングの利点が崩壊します。1つの接続上で20のストリームをマルチプレクシングできても、1つのパケットの喪失がすべての20のストリームを停止させます。😭
これは解決可能な制限ではありません。これは、バイトストリームトランスポートに「ストリーム」という概念が存在しないことを前提としたリクエストマルチプレクシングプロトコルを構築する構造的な制限です。
HTTP/3が実際に変更したこと
HTTP/3はフレームフォーマットを調整したり、新しい機能フラグを追加するだけではなく、TCPをQUICというトランスポートプロトコルに置き換えています。QUICはUDP上に動作します。
QUICはトランスポート層でマルチプレクシングを処理するため、パケットが失われた場合、そのストリームだけがブロッキングされ、他のすべてのストリームは影響を受けません。HOLブロッキング問題は、スタックの適切なレベルで解決されます。これが本質です。
QUICが伴ういくつかの他の特徴があります:
- 接続移行。 QUICは、ソースIP、ソースポート、宛先IP、宛先ポートの4タプルではなく、接続IDで接続を識別します。Wi-Fiからセルラーに切り替える中間で、接続が継続します。これはモバイルアプリにとって重要ですが、サーバー間API呼び出しにはほとんど関係ありません。
- 0-RTTハンドシェイク。 既知のサーバーに接続する場合、QUICはTLS交渉を1回のリターンでスキップし、データを即座に送信できます。再接続時の実際の遅延が改善されます。ただし、0-RTTにはリプレイ攻撃の懸念があります——非イデムなエンドポイントでは、そのトレードオフを理解しない限り使用しないでください。
- 必須TLS 1.3。 QUICは暗号化されていない接続をサポートしません。HTTP/3はTLSなしではあり得ません。
ヘッダー圧縮も変更されました:HTTP/3はHPACKではなくQPACKを使用します。違いは技術的です——QPACKは、ヘッダーがストリーム間で圧縮される場合のHPACKのブロッキング問題を回避します。実際には、差異は観察されません。これはインフラストラクチャの改善です。
機能比較
| 特徴 | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|
| トランスポートプロトコル | TCP | TCP | QUIC (UDP) |
| リクエストマルチプレクシング | なし(複数接続) | はい | はい |
| HOLブロッキング | リクエストレベル | TCPレベル(まだ存在) | なし |
| ヘッダー圧縮 | なし | HPACK | QPACK |
| TLS必須 | いいえ | なし(仕様)、あり(ブラウザ) | あり(必須) |
| 0-RTTハンドシェイク | いいえ | いいえ | はい |
| 接続移行 | いいえ | いいえ | はい |
| サーバープッシュ | いいえ | あり(廃止) | なし(削除) |
APIの遅延にどう影響するか
HTTP/3は特定の状況で最も効果があります。すべての場面で改善されるわけではありません。
パケット損失のあるネットワーク。 LTEや5Gの不完全なカバレッジでAPIにアクセスするモバイルクライアントは、測定可能な改善を受けるでしょう。信頼できるプライベートネットワーク上のデータセンター間のAPI呼び出しでパケット損失がほぼゼロであれば、差は無意味です。
冷たい接続と再接続。 APIクライアントが頻繁に再接続する場合——短命のサーバーファンクション、モバイルアプリの再起動、一時的なコンテナ——0-RTTによりセットアップコストが減少します。長期間オープンな接続は、この恩恵を受けません。
リクエストの量が重要です。 HTTP/2とHTTP/3は、クライアントが多くの並列リクエストを送る場合に特に効果を発揮します。ブラウザが80のアセットを並列でロードする場合、マルチプレクシングによる大きな効果が見られます。REST APIが3つの順序付きリクエストを送る場合、効果ははるかに小さいです。クライアントが発行する並列リクエストの量が多いほど、トランスポートの改善が重要になります。
CDNがこれにどう対応するか
Cloudflareは2019年からHTTP/3をサポートしており、デフォルトで有効にしています。AWS CloudFrontは2022年にサポートを追加しました。Fastly、Akamai、BunnyCDNなどすべてがサポートしています。
アーキテクチャがここに重要です:あなたのCDNはクライアント接続をエッジで終端します。クライアントがHTTP/3を使ってQUICでCDNに接続する場合でも、CDNからオリジンへの接続はほぼ確実にHTTP/1.1またはHTTP/2でTCPで行われます。したがって、CDN上で「HTTP/3を有効にする」ことは、オリジンサーバーに変更を必要としません。
Cloudflareにいる場合は、Speed → Optimization設定を確認してください——HTTP/3(QUIC)はほとんどのゾーンでデフォルトで有効になっています。他のCDNはそれぞれ異なります。これは、チームが行える最も効果的な変更であり、モバイルまたは高遅延パスのクライアントに即時利益をもたらします。
実際に何かするべきか?
CDNの後ろにある場合: HTTP/3が有効になっていることを確認し、それ以上何もしないでください。30秒程度です。
自前でnginxを運営している場合: HTTP/3はnginx 1.25以降(メインラインブランチ——安定版はQUICに遅れています)が必要です。必要な --with-http_v3_module コンパイルフラグと listen 443 quic reuseport ディレクティブを、既存のTCPリスナーに追加してください。ファイアウォールでUDPポート443が開いていることを確認してください——いくつかのネットワーク設定でブロッキングされています。モバイルユーザーにサービスを提供している場合はやや価値がありますが、サーバー間通信のみを行う場合はアップグレードの混乱を避けたほうがよいです。
Caddyを使用している場合: HTTP/3はデフォルトで有効になっており、設定は不要です。
第三者APIに呼び出すクライアントを構築している場合: HTTP/3が得られるかどうかは、呼び出すサーバーに依存します。curlは7.86.0以降で、nghttp3またはquicheと互換性のあるバックエンドをサポートしています。PythonおよびNodeのほとんどのHTTPクライアントライブラリはまだHTTP/3をネイティブにサポートしていません。Goの標準 net/http はサポートしていません;必要であれば、別途 quic-go ライブラリを使用する必要があります。
一つの実用的な注意:サーバーが実際にどのHTTPバージョンを交渉しているかをテストする場合、または --http3 フラグを使用してcurlコマンドを構築する場合、 cURLコマンドビルダー iotools.cloudは、正確なフラグ構文を毎回探す必要を減らすために便利です。
恵 スコアボードが到着しました!
スコアボード ゲームを追跡する楽しい方法です。すべてのデータはブラウザに保存されます。さらに多くの機能がまもなく登場します!
