こんにちは!インフラアーキテクトの私です。日々、ネットワークの海を駆け巡るパケットたちと対話しているのですが、今回はWebの基盤を支える「通信の仕組み」について、とってもエキサイティングなお話をしたいと思います。
皆さんは、普段何気なく見ているWebサイトが、裏側でどのようにデータをやり取りしているか気になったことはありませんか?「URLをクリックしたらページが表示される」、それは当たり前のことですが、その裏側ではネットワークの歴史と、エンジニアたちの熱い泥臭い戦いの歴史が詰まっているんです。
今回は、Web APIやフロントエンドのパフォーマンスを語る上で避けて通れない、「HTTP/2 Multiplexing(多重化)によるヘッド・オブ・ライン・ブロッキングの解消」というテーマに直球で迫ります!小難しい専門用語はなるべく使わず、身近な例えを交えながら一歩ずつ紐解いていきましょう。
—
1. 昔のWebは「一本道の細い道路」だった(HTTP/1.1の限界)
まずは、これまでの主役だった「HTTP/1.1」という通信規約(プロトコル)の世界を覗いてみましょう。
イメージしてみてください。あなたは大きな荷物をたくさん抱えて、遠くの友達の家へ届けに行こうとしています。道路は一本しかなく、しかも車一台がやっと通れるほどの細い山道です。
HTTP/1.1の基本ルールは「一つのコネクション(道路)につき、一度に一つのリクエストとレスポンスしかやり取りできない」というものでした。これを技術用語で「直列処理」と呼びます。
例えば、Webブラウザが1つのページを表示するために、HTMLファイル、画像が10枚、スタイルシートが3枚、合計14個のファイルをサーバーから取ってこなければならないとします。HTTP/1.1の世界では、以下のような手順を踏んでいました。
1. 道路を繋ぐ(TCPコネクションの確立)
2. 「HTMLをちょうだい!」と頼んで、受け取る。
3. 「1枚目の画像をちょうだい!」と頼んで、受け取る。
4. 「2枚目の画像をちょうだい!」と頼んで、受け取る。
……これを14回繰り返す!
「えっ、非効率すぎない?」と思いましたよね。その通り、めちゃくちゃ非効率なんです。ブラウザ側もがんばって、同時にいくつもの道路(最大6本ほどのTCPコネクション)を作って並行してデータを取ろうと努力しましたが、それでも道路の数には限界がありました。
—
2. 悪名高き「Head-of-Line Blocking(HOLB)」の恐怖
ここで、HTTP/1.1が抱える最大の弱点が登場します。それが今回のテーマの鍵でもある「ヘッド・オブ・ライン・ブロッキング(HoLブロック:行頭ブロック)」です。
先ほどの「一本道の細い道路」の例えに戻りましょう。
あなたが14個の荷物を順番に運んでいます。ところが、前から1番目に頼んだ「とびきり大きな画像データ」が、サーバー側の処理が遅くてなかなか届きません。
するとどうなるでしょうか?
その大きな荷物が道路の真ん中で立ち往生してしまい、後ろに控えている「2番目の画像」「3番目のCSSファイル」は、前の荷物が通り過ぎるまで、1歩も動けずに道路で待たされることになりますよね。
これがネットワークの世界で起きるHoLブロックです。一本のTCPという道路の上で、先頭のパケット(データ)が詰まってしまうと、後続のすべてのデータが人質にとられたように足止めを食らってしまうのです。ページの表示が遅延する大きな原因は、まさにここにありました。
—
3. 救世主「HTTP/2 Multiplexing(多重化)」の登場
「この非効率な状況をなんとかしたい!」というエンジニアたちの執念から生まれたのが、次世代の通信規格「HTTP/2」です。そして、その目玉機能こそが Multiplexing(多重化) なのです。
HTTP/2では、サーバーとクライアントの間を結ぶ「たった1本のTCP接続(道路)」の構造をガラリと変えました。
今度の道路は、一本道ではなく「何車線もある巨大なハイウェイ」、しかもそれぞれの車線が透明なパイプラインのように独立しています。技術的にはこれを「ストリーム(Stream)」と呼びます。
郵便配達の仕組みに例えてみよう
HTTP/2の多重化は、まるで「郵便局の仕分けシステム」にそっくりです。
- HTTP/1.1は、1通の手紙が届くまで、次の手紙をポストに投函できないような状態でした。
- HTTP/2では、ダンボール箱をいくつもの小さな「パケット(荷物片)」にバラバラに分解し、それぞれに「これは〇番目の手紙のパーツだよ」というタグ(ストリームID)を貼ります。
- そして、それらのバラバラの荷物を、1本の同じ道路(TCP接続)をごちゃ混ぜにして同時にトラックへ積み込み、一気に送り出すのです。
受取人(ブラウザ)のところに届いたバラバラの荷物は、タグを見て元の形にパズルのように組み立て直されます。
これによって何が起きたか?
もし「1番目の重たい画像データ」の到着が少し遅れても、同じ道路をシェアしている「2番目や3番目のテキストデータ」は、何食わぬ顔で先に到着してブラウザで表示され始めます。「先頭がつかえても、後ろが止まらない」。これが、HTTP/2の多重化によるヘッド・オブ・ライン・ブロッキングの完全な解消です!
—
4. 実務で触れる!HTTP/2の恩恵を受けるための設定
「理論は分かったけれど、実務ではどうやって使うの?」
安心してください。現代のWeb開発やインフラ構築において、HTTP/2は特別なアプリケーションコードを書かなくても、サーバー側の設定を少し変えるだけで恩恵を受けることができます。
例えば、大人気のWebサーバーである Nginx を使って、HTTP/2を有効にする設定を見てみましょう。
NginxでのHTTP/2有効化サンプル設定
server {
# 443ポートでリッスンし、SSL/TLS暗号化を有効にする
# ※HTTP/2は実質的に暗号化(HTTPS)が必須となります
listen 443 ssl http2;
server_name api.example.com;
# SSL証明書と秘密鍵のパスを指定
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
# 推奨されるモダンな暗号化スイートの設定
ssl_protocols TLSv1.2 TLSv1.3;
location / {
# バックエンドのアプリケーション(Node.jsやPythonなど)へ転送
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
# ヘッダー情報の引き継ぎ
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
この設定のポイントは、listen 443 ssl http2; の一文です。これだけで、Nginxとクライアント(ブラウザやAPIクライアント)の間で自動的にHTTP/2のネゴシエーション(お互いの対応確認)が行われ、魔法の多重化パイプラインが開き始めます。
—
5. それでも残る課題:TCPの宿命「トランスポート層のHoLブロック」
さて、ここで少しだけディープな技術の裏話をさせてください。
「HTTP/2でアプリケーション層のヘッド・オブ・ライン・ブロッキングは解決した!」と手放しで喜んでいたインフラエンジニアたちに、新たな壁が立ちはだかりました。それが「TCP自体のヘッド・オブ・ライン・ブロッキング」です。
ここまで「1本のTCP接続という道路」と表現していましたが、TCPというプロトコルには「届いたデータの順番を絶対に守り、抜けがあったら後続を止めてでも再送を要求する」という厳格なルールがあります。
もし、Wi-Fiの電波が悪くて、HTTP/2が使っているその「たった1本のTCP道路」の途中で、ほんの1つだけパケットがロスト(消失)してしまったらどうなるでしょうか?
たとえそのパケットとは全く関係ない別のストリームのデータであっても、下層のTCPが「おい、順番が狂ったから、失くしたパケットが再送されてくるまで全員ストップ!」と、ハイウェイ全体の通行止めをかけてしまうのです。
この「TCPの宿命」を根本から解決するために開発されたのが、さらに次世代のプロトコルである HTTP/3(QUICベース) です。HTTP/3では、TCPではなくUDPをベースにし、ストリームごとに完全に独立したパケットロス処理を実現しています。このあたりのワクワクする話は、また別の機会にたっぷりお届けしましょう!
—
まとめ
今回は、HTTP/2のMultiplexingがもたらすパフォーマンス改善の裏側を、ヘッド・オブ・ライン・ブロッキングの解消という文脈から紐解いてみました。
- HTTP/1.1 は一本道で直列処理だったため、先頭の遅延が全体を止める HoLブロック に悩まされていた。
- HTTP/2 Multiplexing は、1本の接続の中に複数の独立した車線(ストリーム)を作り、データを並行して流すことで HoLブロックを解消 した。
- 実務のインフラ設定でも
http2の有効化はごくシンプルに行える。
インフラやネットワークの世界は、一見難しそうに見えますが、私たちの現実世界の交通網や郵便の仕組みと非常に似通っています。こうした背景を知ることで、API設計やWebシステムのパフォーマンスチューニングが、より一層楽しく、深く理解できるようになりますよ。
それでは、また次回のプロトコル解説の旅でお会いしましょう!
コメント