SPDY (スピーディ) プロトコル (前半部) 日本語訳 11/28/2009版
|先日、Google が SPDY プロトコル (スピーディプロトコル) を発表しました。
私も興味があったので、その仕様書を読みつつ日本語訳を書いてみました。とりあえず、概要 (overview) から接続 (connections) までを翻訳してます。スピーディの特徴を把握することは出来ると思います。
続きは、私が余力があればいずれ書きたいと思います。どなたか書かれましたら教えていただければと思います。
SPDY プロトコル
概要
現行の HTTP のボトルネックのひとつは、HTTP は同時並行性 (concurrency) に関して複数の接続にのみ依存しているということです。これは、接続開始のための余計なラウンドトリップ、開始の遅さ、単一のサーバーに大量の接続を開始することを避けるためのクライアントによる接続制限 (訳注: constant rationing はこのことを指すでしょうか) を含むいくつかの問題を引き起こします。HTTP パイプライニング (pipelining) はそのラインの先頭にてリクエストがブロックされるかもしれないので役に立たず、それに加えて多くのプロキシはパイプライニングをあまりよくサポートしていません。多くの接続を作成しようとするアプリケーションは、ドメイン毎の接続スロットリングを回避するために、多くのサブドメインを作成します。
SPDY はこのような現行の Web アプリケーションに関わるアプリケーション層の問題を解決することを目的とします。同時に Web アプリケーションを書く人の観点でいえば、ごくわずかの変更かあるいは全く変更がないようにします。
簡単に言えば、SPDY は単一の TCP 接続に、多重化された複数の同時平行ストリームのためのフレーミング層 (a framing layer for multiplexing multiple, concurrent streams) を追加します。フレーミング層は HTTP 的な要求応答ストリームに最適化されます。
SPDY セッションは HTTP と比較して、三つの基本的な改良を施します。
- 多重化された要求. 単一の SPDY 接続上で同時に発行できる要求数に上限はありません。単一のチャネル上で複数のリクエストが交互の行き来 (訳注: interleaved) するので、TCP の効率はずっと高まります。
- 優先順位付けされた要求. クライアントはあるリソースを先に到達させることを要求することが可能です。これによって優先度の高い要求が待ち状態でありながら、重要でないリソースによってネットワークチャネルが混雑した状態になることを防ぐことが出来ます。
- 圧縮されたヘッダ. 今日のヘッダは HTTP ヘッダを形作る大量の冗長なデータを送信しています。単一のウェブページは 50 あるいは 100 の従属的なリクエスト (subrequest) を必要とする場合があるので、このデータは重要です。ヘッダを圧縮することで HTTP と比べて待ち時間と大域幅を大幅に節約できます。
注意していただきたいのは、多くの部分で SPDY は既存の HTTP の特徴のセマンティクスをそのまま残そうとしていることです。クッキー、ETag、Vary ヘッダ、Content-Encoding ネゴシエーションなどの全ての機能は、HTTP と全く同様に機能します。SPDY はネットワーク上でデータが記述される方法のみを置き換えるのです。
定義
- 接続 (connection): 二つのエンドポイントの間の TCP レベルコネクション
- エンドポイント (endpoint): 接続のクライアントあるいはサーバーのどちらか
- セッション (session): フレーム化されたデータチャンクの連続 (訳注: a framed sequence of data chunks) フレームは SPDY フレームとして定義されます。以下のフレーム化 (Framing) を参照してください。
- ストリーム (stream): 単一の SPDY セッション内にて、仮想的なチャネルをわたるバイトの双方向の流れ。
HTTP からの主な相違点
SPDY は現行の Web ベースのアプリケーションと可能な限り互換性を保つことを意図しています。これはすなわち、サーバーのビジネスロジックあるいはアプリケーション API の観点からは、何も変更されないことを意味します。これを達成するために、アプリケーション要求及び応答のヘッダーセマンティクスはそのまま保持されます。SPDY は “セッション” を導入しますが、これは HTTP アプリケーション層と TCP トランスポートの間に入り、データの流れを制御します。この “セッション” は HTTP の要求-応答ペアと同種のものです。以下に SPDY と HTTP の違いを示します。
要求
新しい要求を開始するために、クライアントはまず新しい SPDY セッションを作成します。セッションがひとたび作られれば、そのクライアントは要求を運ぶための新しい SPDY ストリームを作ることが可能になります。ストリームを作成することの一部は、HTTP ヘッダブロックを送信することです。SPDY での HTTP ヘッダブロックは現行の HTTP ヘッダブロックとほとんど変わりありません。変更点は以下の点です。
- 要求の第一行は、他の HTTP ヘッダのように、名前/値ペアへと折り畳まれません。第一行のフィールドの名前は method, url, version です。これらのキーは必須です。url は完全に修飾された URL であり、プロトコル、ホスト、ポート及びパスを含みます。
- ヘッダー名の重複は許されません。
- ヘッダー名は全て小文字で表記されます。
- Connection と Keep-Alive は無効となり、存在しても無視されます。
- クライアントは Accept-Encoding: gzip をサポートすることが要求されます。ボディのエンコーディングを指定しないクライアントは、サーバーから gzip エンコードされたデータを受け取ります。
- “host” ヘッダーは無視されます。HTTP URL の ホスト:ポート 部が最終的なホストになります。
- ユーザーエージェントは、gzip と deflate 圧縮をサポートすること期待されます。ユーザーエージェントから送信された Accept-Encoding によらず、サーバーはいつでも gzip あるいは deflate を選択できます。
- POST 固有の変更
- POST 要求はポストの一部としてデータストリームを含むことが期待されます。以下のデータフローを参照。
- Content-Length は単なるデータ長の参考値です (これによってプログレスメータが機能できます)
- チャンクエンコーディングはもはや有効ではありません。
- POST データストリームは長さ 0 のデータフレームで終了します。
応答
HTTP 要求に応答する時は、サーバーはクライアントによって作成された SPDY ストリームを使ってデータフレームを送信します。ヘッダーブロックにボディ部が続く構成であるという点においては、レスポンスは HTTP/1.1 と似ています。しかしながら、いくつか注目すべき変更があります。
- レスポンスステータス行は、他の HTTP ヘッダーのようには名前/値のペアに折り畳まれません。ステータス行の名前は status と version です。これらのキーは必須です。
- もし SPDY 応答が SYN_STREAM の前に発生したなら、それはパラメータを含みます。そのパラメータはクライアントに、このレスポンスを受け取ることになったリクエストの情報を 、url 及び method キーによって含みます。
- ヘッダー名は全て小文字で表記されます。
- Connection と Keep-Alive レスポンスヘッダーはもはや無効です。
- Content-Length は単なる長さのアドバイザリとして扱われます。
- チャンクエンコーディングはもはや無効です。
- ヘッダー名の重複は許されません。
接続
SPDY セッションの最初の実装は TCP の上で動作します。これは今日の HTTP が機能する仕組みと同様です。クライアントは TCP 接続の開始者であることを期待されています。TCP 上で動作するので、信頼性のある通信を確保できます。HTTP とは異なり、SPDY による全ての接続は永続性のある接続になります。HTTP 接続ヘッダーは適用されません。
最高のパフォーマンスのため、ユーザーが現在の接続で参照している全てのページから外部へ出て行くかサーバーが接続を閉じるまでは、クライアントは接続を閉じないことを期待されます。サーバーは可能な限り接続を開いておくようにしますが、必要ならば動きのないアイドル状態の接続を切断することは可能です。
参考資料
タイトルの通り、この日本語訳資料は 2009年11月28日時点のドラフトを元に作成してあります。
最新版は本家 Chromium プロジェクトの SPDY プロトコル仕様書ページをご覧ください。