HTTP(HyperText Transfer Protocol)は、インターネット接続の代名詞として広く認識されています。1991年に誕生し、長い歴史を有します。ウェブへのアクセスを支える通信プロトコルとして、今日では言うまでもありません。
初期のバージョン1.1は依然として最も広く使われていますが、現代では欠点も明らかになってきました。そこでHTTP/2が登場し、HTTP v1.1の多くの問題点を解消しています。
本記事では、HTTP/2の定義、その必要性、利点、欠点、そしてHTTP/1.1との主要な違いについて解説します。
1989年にTim Berners-LeeがHTTPを発明。HTTP/1.1は初の標準化バージョンで、1997年にエンドユーザー向けに利用可能となりました。このバージョンは従来版に比べ大幅な性能向上を実現し、クライアントとサーバ間の通信方法を変えました。しかし、その性質が多くの性能面やAPIセキュリティの隙を生む結果となりました。
HTTP/1は応答速度が遅いことで知られており、ウェブサイトがよりリソースを必要とする中、その効率は低下していました。結果、遅延を抑えページの読み込み速度を上げることが不可欠となりました。
Googleはこれらの問題に着目し、予想通りHTTP/1.xの問題を解決する実験的プロジェクト「SPDY」を2010年に試験運用しました。
数年後、IETF、Google、Microsoft、Facebookが協力し、十分にテストされた新バージョンのHTTPが2015年にリリースされました。
SPDYプロトコルを基に開発されたHTTP/2は、HTTP/1.1の根本的な制約を解消し、インターネットのさらなる発展を目指しています。
HTTP/2は、前作の多くの欠点を解消したHTTPの第2世代です。効率、速度、セキュリティが向上しており、Chrome、Firefox、Internet Explorer、Safariなど主要ブラウザでサポートされています。
HTTP/2は、インターネット上のアプリを簡素化し、速度を上げ、機能を強化することを目指しています。そのために、ページ読み込み時間、リソースの最適化、往復時間(RTT)の短縮に注力しています。
リソース負荷の高いページでは、利用者側で段階的にダウンロードを行うことで使い勝手を向上させます。
HTTP/2の登場は、HTTP/1.1の限界を克服し、より効率的なウェブプロトコルを実現するための試みでした。大きな違いは、HTTP/2に追加・改良された機能にあります。以下にその内容を見ていきます。
HTTP/2が前作に対してどのような変更を加えたのか理解するため、まず基本的な機能と開発の経緯を簡単に振り返ります。
HTTP/1.1
HTTPプロトコルは1989年に、クライアントとサーバ間の通信を可能にする共通言語として開発されました。手順は以下の通りです。
これは一度きりの処理ではなく、ウェブページを正しく表示するために必要な全リソースが揃うまで、両者間で繰り返し行われます。
このリクエストとレスポンスのやりとりは、転送層とネットワーク層を経由してIPスタックとして扱われ、最終的にアプリ層に届きます。では、HTTP/2は同じ状況をどのように処理するのでしょうか。
HTTP/2
HTTP/2は、前作を大幅に向上させるためにGoogleでリリースされました。初めはSPDYプロトコルを基に設計され、マルチプレキシング、ヘッダー圧縮、ストリームの優先順位付けなど、ページ読み込みの遅延を抑える機能が追加されました。リリース後、GoogleはSPDYのサポートを中止し、HTTP/2への移行を宣言しました。
HTTP/2とHTTP/1.1の最大の違いは、バイナリ・フレーミング層にあります。HTTP/1.1とは異なり、HTTP/2はメッセージをバイナリデータに変換してカプセル化しつつ、HTTPの各要素(メソッド、ヘッダー情報など)を保持します。この機能により、gRPCが消費するリソースを削減できます。
これまで説明したように、HTTP/1.1はメッセージを平文で送信しますが、HTTP/2はそれらをバイナリデータに変換し、整理して送信します。これにより、HTTP/2は複数の配信モデルを採用できます。
多くの場合、HTTP GETリクエストに対する初回応答は、完全に読み込まれたページではありません。追加リソースの取得には、クライアントが繰り返しリクエストを送り、TCP接続を再構築する必要があります。
このプロセスは多くのリソースと時間を消費することになります。
HTTP/1.1
HTTP/1.1はサーバとクライアント間に常時接続を設けることで、接続の再確立を省いています。明示的に閉じられるまで接続が維持されるため、クライアントは一つのTCP接続で通信を続けられます。
この手法は性能向上に寄与しますが、一方で問題点も存在します。
例えば、キュー先頭のリクエストが必要なリソースを取得できなければ、後続の全リクエストがブロックされる、いわゆるヘッド・オブ・ライン(HOL)ブロッキングが発生します。
以上から、複数のTCP接続が必要となることが分かります。
HTTP/2
この問題を解決するため、HTTP/2ではバイナリ・フレーミング層が導入されました。リクエストとレスポンスを小さなデータパケットに分割しエンコードすることで、複数のリクエストやレスポンスが並行して処理され、HOLブロッキングの発生が極めて低くなりました。
これにより、HTTP/1.1で問題となっていたHOLブロッキングが解消されるだけでなく、クライアントとサーバ間の並行通信が可能となり、双方の接続管理の制御が向上しました。
HTTP/1.1の問題は大部分解決されましたが、同一リソースを求める複数のデータストリームがHTTP/2の性能を阻害することもあります。これを補うため、HTTP/2にはストリーム優先順位付けの機能が備わっています。
並行してストリームを送信する際、クライアントは各ストリームに1から256の重みを設定して優先度を決めることが可能です。重みが大きいほど優先順位が上がり、サーバはその重みに基づいてデータ取得の順序を決定します。この機能により、プログラマはページ描画の制御をより細かく行えます。
先述のように、GETリクエストによりクライアントはHTMLページを受信します。ページ内容を解析する中で、追加リソースが必要と判断され、さらなるリクエストが発生します。その結果、接続の読み込み時間が延びてしまいます。サーバがクライアントの追加ファイルの必要性を把握していれば、リクエスト前にそれらを送信し、時間を節約できる有効な解決策となります。
HTTP/1.1
これを実現するため、HTTP/1.1ではリソースインラインという手法が用いられ、初回GETリクエストに対してサーバが必要なソースをHTML内に組み込みます。この方法はリクエスト数を減らしますが、非テキスト形式の大きなファイルがページサイズを増大させる欠点もあります。
結果として、接続速度が低下し、得られるメリットが打ち消されます。また、クライアントはHTMLページからインラインリソースを分離できないため、より細かな接続最適化が求められます。HTTP/2はサーバプッシュ機能でこれに対応しています。
HTTP/2
HTTP/2は、初回GETリクエストに対し複数の同時応答をサポートするため、サーバはHTMLページと共に必要なリソースを提供します。これがサーバプッシュと呼ばれるプロセスで、従来のリソースインラインと同様にリソースを送信しつつ、ページとプッシュされたリソースを別々に扱えます。これにより、クライアントがプッシュリソースのキャッシュや拒否を独自に判断でき、インライン手法の欠点が解消されます。
サーバとクライアント間のTCP接続では、双方が受信リクエストを保持するためのバッファ領域を必要とします。
これらのバッファは多数または大容量のリクエストを保持できる場合もありますが、容量が限られていると受信側でバッファオーバーフローが発生し、データパケットが失われる恐れがあります。例えば、バッファが満杯になった後に受信されたパケットは破棄されます。
これを防ぐため、フロー制御機構が送信側から過剰なデータが送られるのを防ぎます。
***
HTTP/1.1
HTTP/1.1のフロー制御は、基本のTCP接続に依存しています。接続開始時に双方が自動的にバッファサイズを設定し、受信側のバッファが満杯になると、利用可能な容量を示すウィンドウ情報を共有します。受信側はこれを確認し、ウィンドウ再開の信号を送ります。
なお、フロー制御は接続の片側のみで実施可能で、HTTP/1.1はTCP接続を使用するため、各接続に個別の制御が必要となります。
HTTP/2
HTTP/2は同一のTCP接続上でデータストリームをマルチプレックスするため、送信層ではなく各機器が個別にフロー制御を行えます。アプリ層で利用可能なバッファサイズの情報を共有し、各機器がマルチプレックスストリーム単位で受信ウィンドウを設定します。さらに、受信ウィンドウの調整は、信号の到達を待たずに即時実行されます。
各HTTP転送には、送信リソースとその特性を記述するヘッダーが含まれます。このメタデータは転送ごとに1KB以上のオーバーヘッドとなり、全体の性能に影響を与えます。これを軽減し性能向上を図るため、圧縮アルゴリズムでHTTPメッセージのサイズを削減する必要があります。
HTTP/1.1
HTTP/1.xでは、gzipなどを用いてメッセージ内のデータを圧縮しますが、ヘッダー部分は常に平文で送信されます。ヘッダー自体は小さいものの、クッキーの使用やリクエスト数の増加によりサイズが大きくなる場合があります。
HTTP/2
この問題に対処するため、HTTP/2はHPACK圧縮を採用し、ヘッダーの平均サイズを縮小します。ヘッダーのメタデータはハフマン符号化によりエンコードされ、大幅なサイズ削減が実現されます。さらに、HPACKは以前のヘッダー値を記録し、クライアントとサーバが共有する動的なインデックスに基づいてさらに圧縮を行います。
Request #1
メソッド: Get
スキーム: https
ホスト: result.com
パス: /resource
accept: /image/png
ユーザーエージェント: Mozilla/5.0…
Request #2
メソッド: Get
スキーム: https
ホスト: result.com
パス: /new_resource
accept: /image/png
ユーザーエージェント: Mozilla/5.0…
パスフィールドを除き、その他すべての項目は同一の値となっています。したがって、2回目のリクエスト送信時には、HPACK形式を用い、共通項目を再構築するために必要なインデックス値のみを転送し、パスフィールドは別の方法でエンコードできます。その結果、両リクエストのヘッダーフレームは以下のようになります。
リクエスト#1用ヘッダーフレーム
:メソッド: Get
:スキーム: https
:ホスト: result.com
:パス: /resource
accept: /image/png
ユーザーエージェント: Mozilla/5.0…
リクエスト#2用ヘッダーフレーム
:パス: /new_resource
最新技術として、HTTP/2には多くの利点と欠点が存在します。以下にその内容を示します。
メリット:
デメリット:
HTTP/3は、クライアントとサーバ間の通信に影響を与える最新のHTTP規格で、APIセキュリティ、信頼性、性能の面で大幅な改良が加えられています。HTTPの基本的な意味論は各バージョンで一貫していますが、HTTP/3はその意味論を基盤トランスポートにマッピングする点で従来と異なります。
HTTP/1.1とHTTP/2はTCPをトランスポートとして使用しますが、HTTP/3はGoogleのQUIC、すなわちUDP上でユーザ空間の輻輳制御を実現するトランスポート層プロトコルに基づいています。
パケットロスの影響低減、ゼロRTT、より強固な暗号化、迅速な接続確立など、HTTP/2の欠点を補う多数の解決策が盛り込まれており、HTTP/3は間もなく標準プロトコルとなるほか、既に多くのライブラリ、インフラ、ブラウザで採用されています。
HTTP/2の影響力と制御力は、サイバー空間において否応なく注目されています。HTTP/2の基本機能は、ウェブアプリの性能を最適化するための高度な制御力を提供します。技術の世界は年々急速に進化しており、先進技術の導入が求められる中、HTTP/3は前作の欠点を補うために開発された新たなプロトコルですが、HTTP/2には依然として多くの役割があり、すぐに姿を消すことはありません。
最新情報を購読