みなさん、こんにちは!技術メディア編集部のメインライターです。
日々のWeb開発やインフラ運用、本当にお疲れ様です。ブラウザを開いて「パッとページが表示される」のが当たり前になった現代ですが、その裏側を支えるネットワークの世界は、実はものすごくドラマチックなんですよ。
今回は、Web通信の主役である「HTTP/2」と、その土台を支える「TCP」の切っても切れない関係についてお話しします。
「マルチプレクシング(多重化)ってすごいらしいけど、裏で何が起きているの?」「パケットロスが起きると息苦しくなるって本当?」そんな疑問を、身近な例えを交えながら一歩ずつ紐解いていきましょう!
難しい用語が出てきても「一歩ずつ理解していきましょう!」の精神で優しく解説しますので、コーヒー片手にリラックスして読んでいってくださいね。
—
1. 昔のWebと今のWeb、何が違うの?
まずは、HTTP/1.1という「昔のルール」と、今回の主役であるHTTP/2という「今のルール」の違いを、郵便配達に例えて見てみましょう。
昔(HTTP/1.1)のやり方:たくさん手紙を出すには?
昔のルールでは、ブラウザはWebサイトの中にある画像やスタイルシート(デザインの指示書)をもらうために、1回につき1つの封筒(TCPコネクション)しか使えませんでした。
「画像が100個あるなら、100回手紙を出して、返事が返ってくるのを順番に待とう!」というスタイルです。これでは郵便配達員(ネットワーク)も大忙しですし、途中で1通でも迷子になると後ろがつかえてしまいますよね。
今(HTTP/2)のやり方:1つの大きなバッグに荷物をまとめる
一方、HTTP/2は違います。「1つの大きなバッグ(1つのTCPコネクション)の中に、いくつもの小さな荷物(ストリーム)をギュッと詰め込んで、同時に運んじゃおう!」という仕組みを使います。これをマルチプレクシング(多重化)と呼びます。
このおかげで、1つの道を同時にたくさんのデータが行き交うことができるようになりました。すごい進化ですよね!……と、ここで話が終わればハッピーなのですが、世の中そんなに甘くありません。この「1つの道にまとめる」という構造が、実は裏で別の問題を引き起こすのです。
—
2. TCPの「おもいやり」ルール:輻輳制御とスロースタート
HTTP/2がどんなに優秀なバッグを用意しても、その荷物を実際に運ぶのは「TCP」という配達員のおじさんです。このTCPおじさん、実はとっても慎重で、真面目な性格をしています。
TCPには、インターネットの道路が渋滞しないようにするための「輻輳制御(ふくそうせいぎょ)」という大切なルールがあります。
スロースタート:最初はゆっくり、少しずつ
TCPおじさんは、通信を始めるとき、いきなり全速力で荷物を送りません。最初は「道が空いているか分からないから、とりあえず控えめに荷物を1個だけ送ってみよう」とスタートします。
相手から「無事に届いたよ!」という返事(ACK)が返ってきたら、「じゃあ次は2個に増やそう、その次は4個、8個……」と、倍々ゲームで運ぶ荷物の量を増やしていきます。
この「最初はゆっくり、徐々にアクセルを踏む」仕組みをスロースタート、一度に送り出せる最大の荷物の量を輻輳ウィンドウ(CWND:Congestion Window)と呼びます。
—
3. HTTP/2の落とし穴:すべての荷物が「1つの道」を共有する恐怖
ここで、HTTP/2のマルチプレクシングと、TCPのスロースタートが組み合わさったときに何が起きるか、想像してみてください。
HTTP/2は、1つのTCPコネクション(1本の道路)のうえで、画像やテキストなど、何十ものデータを同時にやり取りします。つまり、すべてのデータが、たった1つの「輻輳ウィンドウ(CWND)」という限られたスペースを分け合って走っているのです。
パケットロスが起きたときのエース級の足かせ「HOLブロッキング」
もし、この1本の道路の途中で、配達中の荷物が1つだけ行方不明になってしまったら(パケットロス)どうなるでしょうか?
TCPおじさんはルールに厳しいので、こう言います。
「おいおい、途中の荷物が1個消えたぞ! 荷物がバラバラに届くと困るから、紛失した荷物が無事に再配達されるまで、後ろの荷物はすべて足止めだ!」
これが、ヘッド・オブ・ライン(HOL)ブロッキングと呼ばれる現象です。
HTTP/1.1の頃は、複数の道路(複数のTCPコネクション)を使っていたため、ある道路でトラブルがあっても別の道路はスイスイ進んでいました。しかし、HTTP/2は「1つの道路」にすべてを賭けているため、たった1つのパケットが消えただけで、その道路を走るすべてのデータ(Webページ全体)が一時的にピタッと止まってしまうのです。
—
4. 実務で役立つ!NginxでのHTTP/2・TCP設定のヒント
「うわ、じゃあHTTP/2ってパケットロスに弱いってこと? 怖いな……」と思いましたか?
大丈夫です! 現場のインフラエンジニアたちは、このTCPの挙動をコントロールして、少しでも快適に通信できるようにチューニングを行っています。
例えば、Webサーバー(Nginxなど)やOSのネットワークパラメータを調整することで、スロースタートの初期値を大きくしたり、パケットロスへの耐性を高めたりすることができます。
以下に、Linux環境(sysctl)やNginxで意識しておきたい代表的なアプローチを挙げておきますね。
/etc/sysctl.conf のサンプル設定例
LinuxカーネルのTCP挙動をチューニングし、輻輳制御を最適化する
1. 初期輻輳ウィンドウ(initcwnd)の拡張
昔のデフォルトは「3〜4パケット」でしたが、現代のブロードバンド環境に合わせて
最初から多めのパケット(例: 10パケットなど)を送り出すように設定し、
スロースタートの立ち上がりを高速化します。
net.ipv4.tcp_slow_start_after_idle = 0
2. 混雑に強い輻輳制御アルゴリズムの採用
伝統的な「CUBIC」に加え、パケットロスではなく「遅延」をベースに制御する
Google開発の「BBR」アルゴリズムを採用することで、回線の太さを最大限に活かし、
ロスに強い滑らかな通信を実現できます。
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
さらに、NginxなどのWebサーバー側でも、HTTP/2のキープアライブやタイムアウト値を適切に設定し、無駄なコネクションの張り直しを防ぐことが実務では重要になります。
nginx.conf のHTTP/2関連の設定例
http {
# HTTP/2の有効化
server {
listen 443 ssl http2;
server_name example.com;
# クライアントとの接続を維持し、TCPの「スロースタート」を何度もやり直す無駄をなくす
keepalive_timeout 65;
# 1つのコネクションあたりで処理できる最大リクエスト数を調整
http2_max_requests 1000;
}
}
※設定変更を行う際は、必ず事前の検証環境で負荷テスト(ab, wrk, k6など)を行い、システムの挙動を確認してから本番環境へ適用するようにしてくださいね!
—
まとめ:技術のトレードオフを楽しもう
今回は、HTTP/2のマルチプレクシングが、土台であるTCPの輻輳制御やスロースタート、そしてHOLブロッキングにどう影響するかを解説しました。
- HTTP/2は1つのコネクション(道路)で多くのデータを同時に運ぶ(マルチプレクシング)
- そのため、TCPの「輻輳ウィンドウ」という共通の枠組みをみんなで分け合う
- 便利な反面、1つのパケットロスが起きると、道路全体が一時的にストップしてしまう(HOLブロッキング)
- 現場では、BBRなどの最新の輻輳制御アルゴリズムやカーネルチューニングで、この弱点をカバーしている
「効率を求めて1つにまとめると、別の場所で渋滞が起きやすくなる」というのは、なんだか人間の社会や交通事情とそっくりで面白いですよね。
こうしたネットワークの裏側のドラマを想像できるようになると、インフラやWeb開発の仕事がもっともっと楽しくなりますよ。
それでは、次回の技術解説もお楽しみに!
コメント