高速・大規模ネットワーク時代に向けて改良されたHTTP/2プロトコル:Windows Insider用語解説
Webを支える基本プロトコルHTTP/1.1が制定されてから10年以上経ち、新たにHTTP/2の規格が制定されてようとしている。高速・大規模ネットワーク向けに改良されたHTTP/2について解説。
「HTTP/2」は、Webサーバーへのアクセスなどで現在広く使われている「HTTPプロトコル Ver.1.1」(以下HTTP/1.1)の次期バージョンの仕様である。HTTP/1.1との互換性を維持しながらも、より多くのWebページのデータを高速に、効率よく送ることを目的として開発されている。
HTTP/1.1の問題点
昨今のWebサイトではWebページを構成するデータの量が増えており、Webサーバーとブラウザー間でやりとりしなければならないデータの量は飛躍的に増えている。その結果、ページ全体が表示されるのが遅くなりがちだ。表示が遅くなるのには多くの理由があるが、Webサーバーの応答が遅く、サーバーからのデータが滞るからという場合も少なくない。これを解消するには、例えば多数のコネクションを同時に使って必要なデータを素早くクライアントへ転送させるという方法があるが、この方法はサーバーやクライアントの負荷を増やし、余計に遅くさせる可能性がある(よって、実際のWebブラウザーでは最大でも4コネクションぐらいまでに制限している)。また、あるHTTPのリクエスト(クライアントからのコマンド)に対する応答が遅くなっていると、後続の応答まで全てブロックされるというHTTP/1.1の仕様もあり、コネクション数を増やしても効果が得られないことがある。
そこでHTTP/2では、Webサーバーとブラウザー間の実質的な転送速度を向上させることを目的として開発が進められた。具体的には、通信路を(仮想的に)多重化して素早いレスポンスを実現しつつ、データ圧縮によって送信しなければならないデータ量の削減を実現している。
HTTP/2の仕様はすでに開発が完了し、現在はIETFの正式な規格として承認を得るための最終ドラフト段階になっている。順調に進めば、来年早々にも正式なIETFの規格(RFC)として承認される予定である。
HTTP/2の最終ドラフト仕様は以下のサイトで確認できる。
HTTP/2の規格化に関する情報については、以下のページも参照していただきたい。
- Hypertext Transfer Protocol (httpbis)[英語](datatracker.ietf.org)
- HTTP 2.0、ワーキンググループラストコールを開始(Server & Storageフォーラム)
HTTP/2の高速化ポイント
HTTP/1.1はすでに世界中に広く普及しており、今やインターネットの根幹となる重要なプロトコルである。パフォーマンス向上のために新しい規格を制定するからといって互換性がなくなってしまうようなことは許されない。
そこでHTTP/1.1との互換性、相互運用性を維持しつつ、より高速で大容量のデータ通信が求められる現在のネットワーク事情に合わせてHTTPプロトコルの改良案が考案された。ベースとなる技術はいくつかあるが、HTTP/2ではグーグルの開発したSPDYプロトコル(→SPDY関連記事一覧)を大幅に参考にしている。SPDYは、HTTPS通信上で(後述の)多重化を実現し、Webページの素早い表示を可能にする技術である。Chromeブラウザーをはじめ、すでに多くのアプリケーションでサポートされており、Windows 8.1のInternet Explorer 11(IE11)などでも利用可能である(ただしWindows 7上のIE11では利用不可)。
以下に、HTTP/2の概要を示す。
HTTP/1.1との互換性の維持
HTTP/2はHTTP/1.1を置き換えるものではなく、互換性を持たせたまま相互運用できるように設計されている。Webサーバーとブラウザー間では、まず従来のHTTP/1.1に基づいて通信を開始し、お互いがHTTP/2をサポートしていることを確認・了解すると以後はHTTP/2による通信に移行する(一番基本的な接続形態の場合)。これにより、HTTP/2をサポートしていない既存のWebサーバーやWebブラウザーとも相互に運用できるようになっている。
送信データのバイナリフレーム化
HTTP/1.1では、やりとりされるコマンドやパラメーター、データなどは、テキスト形式で表現されていたが(ただし一部のデータはバイナリ形式)、HTTP/2ではコマンドやパラメーターは「フレーム」と呼ばれるバイナリ形式のデータにまとめられて送信される。フレームは、HTTPのコマンドの送信や、その応答ごとに1つずつ使用される。フレームの先頭にはデータ長やコマンド、ストリームID(ストリームについては後述)などが固定フォーマットで埋め込まれているので、(人間にとっては解釈しづらいが)コンピューターにとっては扱いやすくなっているし、全体的なデータ長も短縮できる。
フレームの種類としては、次のようなものが定義されている。
フレームタイプ | 用途 |
---|---|
HEADERS | (圧縮された)HTTPヘッダー情報 |
DATA | HTTPの「リクエスト」や「レスポンス」のボディ部分のデータ |
PRIORITY | 送信するフレームの優先度の指定 |
RST_STREAM | ストリームの終了 |
SETTINGS | 接続に関する各種パラメーターのネゴシエーション |
PUSH_PROMISE | サーバー側からのプッシュ要求 |
PING | ストリームの生存確認 |
GOAWAY | コネクションの終了 |
WINDOW_UPDATE | フロー制御用 |
CONTINUATION | 継続フレームの指定 |
HTTP/2の主なフレームタイプ |
フレームサイズはデフォルトでは最大16,384bytesまでだが(これ以上になる場合は分割して送信する)、最初にネゴシエーションすれば最大16Mbytesまで拡大できるので、今後、より高速なネットワークが開発されても利用できるだろう。
多重化ストリーム通信
HTTP/1.1ではWebサーバーとWebブラウザー間で「コネクション」と呼ばれるTCPのセッションを確立して通信していた。そして性能を上げるために、このコネクションを同時に複数接続していた(最大コネクション数はシステムにもよるが、2〜4セッション程度)。
HTTP/2ではコネクションの中に新たに「ストリーム」という仮想的な通信路を開設し、それを使って「フレーム」を送受信する。ストリームは双方向に通信可能な通信路であり、通常はHTTPのコマンドを送ると、相手側からそれに対する応答が同じストリーム経由で返される。1つのコネクション中に複数のストリームを作ると、HTTP/1.1で複数コネクションを使ったのと同等以上のことを実現できる。複数のコネクションで1つずつHTTPコマンドを送るのと(HTTP/1.1方式)、1つのコネクションで複数のストリームを扱う(HTTP/2方式)のでは、機能的には同じように見えるが、ネットワーク全体(のリソースの消費など)でみると、圧倒的に後者の方がシステム(クライアントやサーバーだけでなく、経路の途中にあるルーターやファイアウォール、Proxyサーバーなども含む)に対する負荷が少なくなる。HTTP/2では、クライアントとサーバー間のコネクションは基本的には1つだけにして、より長く維持することが求められている。
HTTP/2のコネクションとストリーム
HTTP/2では、1つのTCP/IPのコネクションの中に複数の仮想的なストリームを開設し、その中にデータ(フレーム)を送信する。ストリーム番号は、クライアントからサーバー方向が奇数、逆方向が偶数である。HTTPによる通信開始時のセッションはストリーム1になる。
HTTP/1.1でも「パイプライン」機能を使えば、1つのコネクションで複数のリクエストを連続して送信することが可能だったが、その場合は、レスポンスは送信したリクエスト順になる。だがHTTP/2のストリームではレスポンスの順番を変更できるので、例えばサーバー側の処理が重い場合は、それ以外の軽い処理のレスポンスを先に返す、といったことが可能になる。
HTTPのリクエストとレスポンス
HTTP/1.0ではリクエストを1つ送ってはレスポンスを待つ、という方式だったので、ネットワークの遅延時間(レイテンシ)が大きいと、応答がどんどん遅くなる。HTTP/1.1のパイプラインでは、複数のリクエストを同時に送信でき、ネットワークの遅延を(見掛け上)隠ぺいできる。だがHTTPのリクエストは逐次処理されるため、あるリクエストの応答が滞ると、後続の応答も止まってしまう。HTTP/2では処理が完了したものから順に(順不同で)レスポンスが返されるため、停滞の影響を受けにくい。
■優先度制御
ストリームには「優先度」を指定することもでき、後から緊急度の高いリクエストを送って、その結果を先に返すように要求することもできる。
■フロー制御(ウィンドウ制御)
HTTP/2では通信の状態を制御する機能として、「フロー制御(ウィンドウ制御)」機能も用意されている。一度に送信可能なデータ量を抑制して受信側のバッファーがあふれてリソース不足になるのを防いだり、逆に大きなウィンドウサイズを指定して、巨大なデータを(細切れにせず)効率よく送信させたりできる。従来のHTTP/1.1ではTCP/IPのプロトコルスタックに含まれるウィンドウ制御に依存していたが、HTTP/2ではWebサーバーやアプリケーションがある程度制御できるようになる。
■エラー発生時の処理の改善
HTTP/2では、より信頼性の高いエラー処理ができるようになっている。HTTP/1.1ではエラーが発生した場合、サーバーがそのリクエストを受け付けて処理したのか、それとも単にリクエストが届いていないのか、などを区別する方法がなかった。処理内容によっては、リクエストを再送して再実行すると不具合を起こすものもあり(例えば削除ボタンを間違って2回クリックした状態になってしまう、など)、注意してシステムを設計する必要がある。HTTP/2では、ストリームを使うことにより、どのストリーム番号の処理まで完了したかをクライアント側から確実に確認できるようになっており、より信頼性の高いシステムを構築できる。
HTTPヘッダーフィールドのエンコードによる圧縮
HTTPのリクエストとレスポンスには、「HTTPヘッダー」と呼ばれるテキストデータが含まれている。この部分は長さがある割には決まった(変わることがほとんどない)文字列も多く、また連続する複数のHTTPヘッダーを観測して比較すると、その差が少ないことが多い。そこで、このHTTPヘッダー部分を何らかの方法で圧縮できれば通信データの削減につながり、パフォーマンスの向上が期待できる。
HTTP/2のベースとなったSSL/SPDYでは、HTTPヘッダー部分をgzipやdeflateアルゴリズムで圧縮していたが、その後この方式に対する脆弱性などが見つかり(CRIME/BREACHアタック→Wikipedia参照。ヘッダー部分の圧縮率を観測することによって、ヘッダー中のデータを推定する攻撃方法)、HTTP/2では別の方法として「HPACK(Header Compression for HTTP/2)」という方法が採用されている。これは次のようないくつかの手法を組み合わせた圧縮方法である。
方法 | 意味 |
---|---|
ハフマン符号化 | ヘッダー中に多く出てくる「文字列」や「符号無し数値」の文字列表記が短くなるように、ビットレベルでハフマン符号化(※)する |
静的テーブルインデックス | よく使われるヘッダー中の単語(GETやPOST、http、https、allow、cookie、Expires、host、referrerなど。約60個が定義されている)をあらかじめ決められた数値データに置き換える |
ヘッダーテーブルインデックス | ヘッダー中に含まれるフィールド(名前と値の組)をテーブルに保存しておき、以前と同じフィールドが出てきたら、文字列ではなく、表のインデックス番号だけを送信する。このために、Webサーバーとブラウザーは、ストリームごとの「状態」をそれぞれ管理している |
HTTP/2ではいくつかの手法を組み合わせてデータを圧縮している。
※ハフマン符号とは、データの出現頻度が高いほど短いデータ表現になるように符号化する方式。詳細は「データ量を操る圧縮/展開を究めよう」を参照。
サーバープッシュによるデータ送信
これはWebサーバー側からWebブラウザーに対して、あらかじめ必要となるデータを送信しておく機能である。例えば/index.htmlを表示するためにsite.cssとsitelogo.pngが必要なことが分かっている場合、/index.htmlが要求されたときに、あらかじめsite.cssとsitelogo.pngも送信する、といった用途に利用できる。
HTTP/2規格の今後
HTTP/2は現在最終ドラフト段階にあり、正式に承認され次第、各Webサーバーやブラウザー、ライブラリなどに正式に実装されるだろう。現在の実装状況は次の通りである。IEでも、次期IEに対しては「In Development」となっているので、来年中には利用できるようになるだろう。HTTP/2の普及は意外と早そうである。
Copyright© Digital Advantage Corp. All Rights Reserved.