こんにちは!技術メディア編集部のシニアネットワークアーキテクトです。
日々のWeb開発やインフラ運用の現場で、ふと「なぜこのサイトの読み込みがこんなに速いんだろう?」「お、HTTP/2が効いてるな」と感じる瞬間はありませんか?前世代のHTTP/1.1から劇的な進化を遂げたHTTP/2。その最大の目玉といえば、1本の太いパイプ(TCP接続)の中で、画像もCSSもテキストも同時にやり取りする「マルチプレクシング(多重化)」ですよね。
「お、なんだかスマートで効率が良さそうだぞ!」と思いますよね。
しかし、現場のインフラエンジニアとして少し意地悪な視点を向けてみると……実はこの仕組み、裏側で「TCPの輻輳制御(ふくそうせいぎょ)」という交通ルールと、ちょっぴり複雑なバトルを繰り広げているのです。
今日は、パケットたちがルーターの海をどう泳ぎ、TCPの制御とどう影響し合っているのか。身近な例えを交えながら、一歩ずつ優しく紐解いていきましょう!
—
1. HTTP/1.1の「大名行列」とHTTP/2の「相乗りバス」
まずは、私たちが使っている「通信の土台」のお話から。
Webブラウザがサーバーから画像やデータを取ってくるとき、通信の大部分はTCP(Transmission Control Protocol)という信頼性重視のプロトコルに支えられています。これは例えるなら、「荷物が確実に届くように、受領確認をしながら進む配達トラック」のようなものです。
HTTP/1.1の限界:車は1台ずつしか通れない!
昔のHTTP/1.1では、1つのTCP接続につき、同時に1つのファイルしかやり取りできませんでした。
ブラウザが「画像ファイルを10個ちょうだい!」と言ったら、サーバーは1個目を送って、ブラウザが「受け取ったよ!」と返事をするまで、2個目のファイルは順番待ち。まるで、狭い一本道に大名行列のように車が連なっている状態(Head-of-Line Blocking:行頭ブロック)でした。
これを解決するために、ブラウザはわざわざ4〜6本のTCP接続を同時に張って、無理やり並行して走らせるという荒技を使っていました。
HTTP/2の登場:1台のバスにギュッと詰め込む!
「いやいや、何本も道路を作るのってもったいなくない?」ということで登場したのがHTTP/2です。
HTTP/2では、たった1本のTCP接続(一本の太い道路)の中に、細かく切り分けた荷物のパケット(これをストリームと呼びます)を何個も同時に乗せて走らせます。
例えるなら、今までは家族全員が別々の軽トラで荷物を運んでいたのを、「大きな一台の相乗りバスに全員分の荷物を積み込んで走る」ようにしたイメージです。道路の混雑は一気にスッキリしますよね。
—
2. 快適なバスの旅に立ちはだかる「TCP輻輳制御」の壁
さて、ここからが本題です。
HTTP/2が導入した「1本の太いTCP接続による多重化」は、一見すると完璧に見えますが、下を支えるTCPの性質と組み合わさると、時にドラマチックな事件を引き起こします。
それが、「TCPの輻輳制御(Congestion Control)」との関係です。
TCP輻輳制御ってなに?
TCPは、インターネットという「世界中の誰もが使っている混雑した道路」を走ります。道路が渋滞しているのに、我先にとスピードを上げまくったら、事故(パケットロス)が起きて大渋滞になりますよね。
そのため、TCPには「最初はゆっくり走り、周りの様子を見ながら徐々にスピードを上げる(スロースタート)」、そして「混んできたらスピードをグッと落とす」という自衛の仕組みが備わっています。代表的なアルゴリズムに、おなじみの `CUBIC` や、最近のトレンドである `BBR` などがあります。
「1本のバス」が抱えるジレンマ
ここで、HTTP/2の「1本のバス(TCP接続)」の特性を思い出してください。
HTTP/2は、この1本のバスの中に「CSS」「JavaScript」「画像A」「画像B」……と、数多くのリクエストを相乗りさせています。
ここで、もし「画像A」のデータの一部が、途中のルーターの混雑で消えてしまった(パケットロス)としましょう。
HTTP/1.1(昔の軽トラ複数体制)であれば、画像Aの軽トラがパンクしても、隣を走っている画像BやCSSの軽トラはスイスイ目的地に到着できました。
しかし、HTTP/2(相乗りバス)の場合、どうなるでしょうか?
TCPは信頼性を最優先するため、「消えたパケット(画像Aの欠片)が安全に再送されて届くまでは、バス全体の進行をストップ(または減速)させろ!」という命令を出します。
その結果、何が起きるか。
「無事に届いているはずのCSSやJavaScriptまでもが、画像Aのせいで足止めを食らう」という現象が起きます。これが、HTTP/2のレイヤーではなく、TCPレイヤーで発生する「ヘッドオブラインブロッキング(Head-of-Line Blocking)」です。
—
3. 現場で役立つ!NginxでのTCP・HTTP/2チューニングアプローチ
「うわ、じゃあHTTP/2って実はボトルネックになりやすいの?」と不安になった方、ご安心ください。現場のインプラ・ネットワークエンジニアたちは、この特性を理解した上で様々なチューニングを行っています。
例えば、Webサーバーの代表格である Nginx では、TCPの挙動やHTTP/2のストリーム制御を環境に合わせて最適化します。実際の現場でよく見かける設定のヒントを覗いてみましょう。
/etc/nginx/nginx.conf またはバーチャルホスト設定の一例
http {
# HTTP/2を有効化
listen 443 ssl http2;
# 1つの接続(TCPコネクション)あたりに許可する最大ストリーム数
# 無制限に増やすとサーバーのメモリやTCPウィンドウサイズを圧迫するため適切に制限します
http2_max_concurrent_streams 128;
# TCPの輻輳制御アルゴリズムやウィンドウサイズをOS側(Linuxカーネル)で最適化するための指針
# ※実際の輻輳制御アルゴリズム(CUBICやBBR)の指定は、Nginxの設定ではなく
# Linuxカーネル側(sysctl.conf)でグローバルに設定します。
}
Linuxカーネル側でのTCPチューニング(sysctl.conf)
HTTP/2のパフォーマンスを最大限に引き出すためには、TCPが最初からスピードを出せるように(スロースタートの初期ウィンドウサイズを大きくする)、以下のようなカーネルパラメータを調整することが実務ではよく行われます。
/etc/sysctl.conf の設定例
TCPの輻輳制御アルゴリズムとしてBBRを使用する(Googleが開発した次世代アルゴリズム)
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
初期輻輳ウィンドウ(initcwnd)を広げ、最初からアクセルを踏み込めるようにする
(※クラウド環境やネットワーク環境のRTTに応じて適切に調整してください)
※近年のLinuxカーネルではデフォルトで最適化されていますが、確認は必須です。
`BBR` などのモダンな輻輳制御アルゴリズムは、従来のパケットロスを基準にした `CUBIC` と異なり、「ネットワークの帯域幅と遅延(RTT)」をリアルタイムに計測して最適なスピードで流すため、HTTP/2のマルチプレクシング環境下でも渋滞を起こしにくく、非常に相性が良いとされています。
—
4. そして未来へ:HTTP/3(QUIC)が解決する世界
さて、ここまでHTTP/2とTCPの切っても切れない関係(愛憎劇)を見てきました。
「1本の太い道路(TCP)」であるがゆえの宿命、すなわち「途中で1つでも荷物が引っかかると、後ろが全部つかえてしまう」というTCPレイヤーのヘッドオブラインブロッキング。
この根本的なジレンマを解決するために生まれたのが、現在普及が進んでいるHTTP/3です。
HTTP/3は、トランスポート層にTCPではなく「QUIC(クイック)」という、UDPをベースにした新しい規格を採用しています。
QUICの世界では、TCPの代わりにUDPを使いつつ、接続の管理をストリーム単位で完全に独立させます。つまり、「バス」の概念を捨てて、それぞれが独立した「ドローン」のように荷物を飛ばすイメージです。これにより、あるストリームでパケットロスが起きても、他のストリームはビクともせず目的地へ飛び続けます。
—
まとめ:一歩ずつ、パケットの旅路を想像してみよう
いかがでしたでしょうか?
ネットワークの世界は、一見すると複雑な専門用語の羅列ですが、私たちが普段暮らしている道路の交通事情や、荷物の配達システムに置き換えてみると、エンジニアたちがなぜそのプロトコルを作り、どうチューニングしようとしているのかがスッと見えてきますよね。
- HTTP/2は1本のTCP接続で複数のリクエストを同時に運ぶ(マルチプレクシング)。
- しかし、その大元を支えるTCPが「安全第一(輻輳制御)」で動くため、1つのパケットロスが全体の足止め(HoLブロッキング)になるリスクを抱えている。
- 現場では、BBRなどのモダンな輻輳制御やカーネルチューニングを駆使して、この通信のボトルネックに立ち向かっている。
ネットワークやインフラに触れ始めたばかりのあなたも、「今、ブラウザとサーバーの間で、どんなパケットの車列が走っているかな?」と想像するクセをつけてみると、日々の開発やトラブルシューティングが何倍も楽しく、そして深みのあるものになりますよ。
それでは、また次回の技術探訪でお会いしましょう!
コメント