こんにちは。CMO室 エンジニアの石澤 (@summerwind) です。
少し前になりますが、HTTP/2の基本的な仕組みを1時間程度で理解することを目的とした「HTTP/2 入門」という勉強会を社内で開催しました。今回はこの場をお借りして、その時の勉強会資料と、HTTP/2の特徴についてを簡単にご紹介したいと思います。
勉強会資料
HTTP/2のこれまで
HTTP/2の仕様策定は、2012年の初めごろからIETFのhttpbisワーキンググループにおいて始まりました。2012年6月には仕様策定の議論の起点となる仕様が複数提案され、ワーキンググループはそのなかから、Googleが開発していたSPDYをHTTP/2のベースに選択しました。これには、GoogleがすでにSPDYを実サービスやChromeに適用し、実際に運用しているという背景があったのが大きなポイントだったようです。
ここからワーキンググループではSPDYの仕様を元にさまざまな議論がおこなわれ、2013年7月前半にはHTTP/2の最初の実装向け草案 (draft-ietf-httpbis-http2-04) が公開されました。 その後、実装向け草案に準拠した実装を使ってプロトコルの動作を確認する相互運用テストや、議論をもとにした仕様のブラッシュアップなどが繰り返され、現在 (2014年6月時点) ワーキンググループでは、ラストコールに向けて最終的な仕様をまとめる段階に入っています。また、最新の草案としては13番目の草案 (draft-ietf-httpbis-http2-13) が公開されています。
HTTP/2の特徴
HTTP/2の草案に書かれている以下の一節にもあるように、HTTP/2は既存のHTTPセマンティクスに対してより最適化されたマッピングを定義して、パフォーマンスを向上させることを主な目的としています。
This document addresses these issues by defining an optimized mapping of HTTP's semantics to an underlying connection. Specifically, it allows interleaving of request and response messages on the same connection and uses an efficient coding for HTTP header fields. It also allows prioritization of requests, letting more important requests complete more quickly, further improving performance.
この目的をふまえ、ここからはHTTPのパフォーマンスを改善するために、HTTP/2から新たに導入される特徴などを簡単にご紹介します。ここで紹介する特徴についての説明は、上記の勉強会資料にも記載されていますので、あわせてご覧ください。
バイナリフレームの採用
最初の特徴としてあげられるのはバイナリフレームの採用です。従来のHTTPではリクエストやレスポンスのフォーマットとしてテキストを使用してきましたが、HTTP/2ではより効率的に情報をやりとりするために「フレーム」と呼ばれるバイナリ形式のフォーマットを採用しています。
フレームにはその用途にあわせていくつかの種類が用意されており、従来のHTTPのリクエストやレスポンスの内容は、全てフレームにマッピングされます。例えば、HTTPヘッダーはHEADERSフレーム、レスポンスのペイロードなどはDATAフレームといった具合です。
以下は、最新の実装草案で定義されているフレームの種類とその役割です。
種類 | 用途 |
---|---|
DATA | リクエストボディや、レスポンスボディを転送する |
HEADERS | 圧縮済みのHTTPヘッダーを転送する |
PRIORITY | ストリームの優先度を変更する |
RST_STREAM | ストリームの終了を通知する |
SETTINGS | 接続に関する設定を変更する |
PUSH_PROMISE | サーバーからのリソースのプッシュを通知する |
PING | 接続状況を確認する |
GOAWAY | 接続の終了を通知する |
WINDOW_UPDATE | フロー制御ウィンドウを更新する |
CONTINUATION | HEADERSフレームやPUSH_PROMISEフレームの続きのデータを転送する |
ストリームによる多重化
2つ目の特徴は「ストリーム」です。従来のHTTPでは、リクエストとレスポンスの組を1つずつしか同時に送受信できないことが、パフォーマンス上のボトルネックになっています。この問題を改善するべくHTTP/1.1では新たにパイプラインが導入されましたが、一部のレスポンスに時間がかかるような場面でレスポンスが詰まってしまう問題などがあり、広く使われてはいません。そこで、HTTP/2では1つの接続上にストリームと呼ばれる仮想的な双方向シーケンスを作ることでこの問題に取り組んでいます。
1つの接続上に作られた複数のストリーム上では、複数のフレームを同時並行で転送できます。例えば、あるストリーム上ではリクエストにあたるフレームが送信中でも、別のストリームではレスポンスにあたるフレームを受信するといったことが可能になります。これにより、全体的なパフォーマンスが向上します。
ヘッダー圧縮
HTTPのリクエストやレスポンスに含まれるHTTPヘッダーを見てみると、同じデータ (例えば、User-AgentヘッダーやCookieヘッダーなど) が毎回送信されていて無駄だな、と感じたことがある方も多いのではないでしょうか。 SPDYでは、HTTPヘッダーをgzipで圧縮して転送量を削減する仕組みを導入していましたが、CRIMEと呼ばれる攻撃手法が見つかったため、この圧縮を無効化、あるいは圧縮率を下げる必要が出てしまいました。
そこで、HTTP/2では「HPACK」と呼ばれる新たなヘッダー圧縮方式が導入されました。HPACKは、1度送信したヘッダーは基本的には再度送信することはなく、新たに送信が必要なヘッダーのみを差分として抽出して送信することで、転送量を削減します。また、Static Tableと呼ばれる、よく利用されるヘッダーとIDの変換テーブルを用意することで、ヘッダーをシンプルなIDに変換して送信できるようになっています。
サーバープッシュ
SPDYの仕様に含まれていた「サーバープッシュ」と呼ばれる機能もHTTP/2に引き継がれました。これは、クライアントのリクエストなしに、サーバーからレスポンスをプッシュするための仕組みです。
例えば、CSSファイルと画像ファイルへのリンクを1つずつ含むHTMLファイルを、ブラウザーが読み込む状況を想像してみましょう。 一般的なブラウザーはページをレンダリングするために、サーバーからHTMLファイルを取得した後、さらにCSSファイル、画像ファイルをそれぞれサーバーから取得するかと思います。
このような状況で、もしサーバーが「このHTMLファイルのレンダリングには、CSSファイルと画像ファイルも必要」ということが分かっていた場合は、サーバープッシュの出番です。サーバープッシュを使うと、以下の図のようにHTMLファイルのレスポンスを返す前に、ページのレンダリングに必要なリソースを事前にブラウザーに送信しておくことができます。
サーバープッシュで送られてきたリソースはクライアント側で一度キャッシュされてから、使用されます。このように、サーバープッシュを使用すれば、クライアントはリクエスト分のレイテンシを短縮でき、リソースの読み込みパフォーマンスが向上します。
ストリームの優先度
先ほど、リクエストとレスポンスを同時並行で処理するためのストリームの仕組みについて説明しましたが、ストリームには優先度を設定することもできます。優先度を設定することで、クライアントはサーバーに対してどのリクエストを優先的に処理して欲しいのかを伝えることができます。もしサーバーが正しく優先度を処理できれば、クライアントは期待した通りの順序でリソースを受け取ることができます。
例えば、ブラウザーがCSSファイルと画像ファイルを並行してリクエストしている場面では、レンダリングへの影響が大きいCSSファイルを先に取得する必要があります。このような場面で、クライアントはCSSファイルへのリクエストを送信しているストリームの優先度を上げることで、CSSファイルを優先的に取得できる可能性があります。
最後に
HTTP/2のこれまでと主な特徴についてを簡単にまとめてみましたが、いかがでしたでしょうか。
だいぶ複雑なプロトコルになったな、と感じられた方もいるかもしれません。HTTP/2はパフォーマンスの改善に強くフォーカスして仕様が策定されており、telnetコマンドから気軽に試せるHTTP/1xのシンプルさが失われつつあるのは、個人的にも少し残念ではあります。
しかし、Yahoo! JAPANのように膨大なトラフィックを生み出しているサービスや、レイテンシが比較的大きいモバイル環境向けのサービスなどにHTTP/2を適用することで、通信パフォーマンスの改善によるサービス体験の向上やトラフィックの削減といった効果が大きく得られるのでないかと考えています。
今回紹介した特徴や機能を実装したHTTP/2のサーバー/クライアントの実装は、すでに複数公開されていますので、実際にHTTP/2を使った検証などをおこなうことができます。 Yahoo! JAPANでも現在、Apache Traffic ServerのHTTP/2対応に取り組んでいます。次の記事ではそのあたりの紹介を予定しておりますので、ご期待ください。
参考資料
こちらの記事のご感想を聞かせください。
- 学びがある
- わかりやすい
- 新しい視点
ご感想ありがとうございました