「SPDY」の版間の差分
(同じ利用者による、間の4版が非表示) | |||
行1: | 行1: | ||
− | [[SPDY]] とは、[[HTTP/2 | + | [[SPDY]] とは、[[HTTP/2|HTTP 2.0]]の起草になった通信プロトコルです。[[SPDY]]を用いることで、ウェブページのロードを高速化できます。 |
'''読み方''' | '''読み方''' | ||
行6: | 行6: | ||
== 概要 == | == 概要 == | ||
+ | HTTP/1系のプロトコルでは、仕様によりボトルネックを多く抱えていました。[[SPDY]]をセッションレイヤーに組み込むことにより、HTTPを速くします。 | ||
+ | |||
* [[ウェブブラウザ]]のサイトの読み込み時間を短縮する | * [[ウェブブラウザ]]のサイトの読み込み時間を短縮する | ||
* ウェブコンテンツの変更を必要としない | * ウェブコンテンツの変更を必要としない | ||
* 既存の[[Webサーバ]]との互換性を維持できる | * 既存の[[Webサーバ]]との互換性を維持できる | ||
+ | == HTTPの通信のボトルネック == | ||
+ | * 1回のコネクションにつき、1つのリクエストしか送信できない | ||
+ | * リクエストがクライアントからしか開始できない | ||
+ | * リクエストヘッダとレスポンスヘッダが圧縮できず、サイズが大きい | ||
+ | * ヘッダが冗長である | ||
+ | * データ圧縮が強制ではない | ||
+ | === 並列TCPコネクションの問題点 === | ||
+ | HTTP/1の実装のボトルネックの1つは、並列処理のためのTCPの複数のコネクションです。 | ||
+ | # 接続により発生するラウンドトリップタイム | ||
+ | # [[スロースタート]] | ||
+ | # クライアントの1つのサーバに対する複数接続の制限 | ||
+ | |||
+ | 1 は、[[3ウェイ・ハンドシェイク]]のパケットの往復のことです。並列実行のために、このパケットがネットワークに流れます。 | ||
+ | |||
+ | 2 の[[スロースタート]]の問題は、[[TCP]]のウィンドウサイズが十分に大きくなるまでに時間がかかることです。ウィンドウサイズは、通信が進むにつれて、サイズが大きくなります。しかし、並列コネクションで通信する場合、ウィンドウサイズが十分に大きくなる前にデータの送受信が完了してしまいます。単一のコネクションで、ウィンドウサイズが大きい状態で通知んするほうがパケットの往復する数を減らすことができます。並列で接続している場合、それぞれのコネクションは、小さいウィンドウサイズで送受信することになるので、パケットの数が増えてしまいます。 | ||
+ | |||
+ | 3 は、サーバのコネクション(リソース)を使いきらないように、クライアントが1つのサーバあたりの接続性を抑制しているため、並列数が一定以上上げられない、ということになります。 | ||
+ | == HTTP 1.1 == | ||
+ | HTTP 1.0の問題がHTTP 1.1で解決されています。 | ||
+ | * Keep Aliveにより、接続を使いまわすことができます。 | ||
+ | * Keep Alive の問題は、同時に複数のリクエストが送信できないことです。現在送信中のHTTPリクエストに対するHTTPのレスポンスが返ってくるまで、次のリクエストが送信できません。 | ||
+ | * アクセスの多いサイトでは、Keep Aliveをオンにしていると接続を使いきってしまい、新しく接続してきたクライアントの接続を受け入れられなくなるため、十分なリソースがないと Keep Alive が使えないケースがあります。 | ||
+ | == piplining == | ||
+ | pipliningは、HTTPレスポンスの受信の失敗や受信の遅延により、pipline上の他のHTTPリクエストやレスポンスの送受信が失敗か、遅延を引き起こしてしまいます。 | ||
+ | 並列のリクエストのいずれかが失敗すると、TCPコネクションの接続確立からやり直す必要があります。 | ||
+ | == SPDYの特徴 == | ||
* [[SPDY]]は、バイナリプロトコルであるため、HTTPヘッダデータのサイズを小さくできます。 | * [[SPDY]]は、バイナリプロトコルであるため、HTTPヘッダデータのサイズを小さくできます。 | ||
* ストリームベースの多重化により、GETに対して、コンテンツを複数並列で返すことができます。 | * ストリームベースの多重化により、GETに対して、コンテンツを複数並列で返すことができます。 | ||
+ | * クライアントは、リクエストに優先度がつけられます。 | ||
+ | * ヘッダは、デフォルトで圧縮され、不要なヘッダは削除されます。 | ||
* コンテンツをブラウザにキャッシュし、ヒットしないときだけサーバに取りに行きます。 | * コンテンツをブラウザにキャッシュし、ヒットしないときだけサーバに取りに行きます。 | ||
+ | * サーバプッシュ通信をサポートします。 | ||
+ | |||
+ | |||
+ | [[SPDY]]では、TCPコネクション上に複数の論理的なストリームを構築します。それぞれのストリームは独立し、リクエストの順番とレスポンスの順番に制約はありません。 | ||
+ | ストリームの制御には、データを含まない専用のコントロールフレームを用います。それぞれのコントロールフレームは、Stream-IDを持ち、このIDにより、各ストリームは区別されます。 | ||
+ | データ本体は、データフレームとして送信されます。 | ||
+ | |||
+ | [[SPDY]]は、ストリームのライフサイクルの管理のために3つのコントロールフレームを定義しています。 | ||
+ | ; SYN_STREAM:新しいストリームを開きます。 | ||
+ | ; SYN_REPLY: リモートアックノレッジメント | ||
+ | ; RST_STREAM:ストリームを閉じます。 | ||
+ | |||
+ | == ネットワークの層とプロトコルの対応 == | ||
+ | [[SPDY]]は、セッション層にあたります。 | ||
+ | {|class="wikitable" | ||
+ | |+ ネットワークの層とプロトコル | ||
+ | ! 層 | ||
+ | ! プロトコル | ||
+ | |- | ||
+ | | アプリケーション層 | ||
+ | | HTTP | ||
+ | |- | ||
+ | | セッション層 | ||
+ | | SPDY | ||
+ | |- | ||
+ | | プレゼンテーション層 | ||
+ | | SSL | ||
+ | |- | ||
+ | | トランスポート層 | ||
+ | | TCP | ||
+ | |} | ||
== SPDYの環境 == | == SPDYの環境 == | ||
行18: | 行79: | ||
[[Chrome]]や[[Firefox]]などのブラウザは、[[SPDY]]に対応しています。 | [[Chrome]]や[[Firefox]]などのブラウザは、[[SPDY]]に対応しています。 | ||
[[Apache HTTP Server]]は、 [[Apache mod spdy]]を組み込むことで利用できます。 | [[Apache HTTP Server]]は、 [[Apache mod spdy]]を組み込むことで利用できます。 | ||
+ | |||
+ | [[SPDY]]に対応している[[Webサーバ]], [[プロキシ]] を挙げます。 | ||
+ | |||
+ | * [[Apache HTTP Server]](httpd) - [[Apache mod spdy]] | ||
+ | * Apache Traffic Server(ATS), [[プロキシ]] | ||
+ | ** https://issues.apache.org/jira/browse/TS-2729 | ||
+ | ** http://techblog.yahoo.co.jp/infrastructure/http2/http2_2/ | ||
+ | * node.js spdyモジュール | ||
+ | ** sudo node install -g spdy | ||
+ | ** [http://kaworu.jpn.org/javascript/node.js%E3%81%A7SPDY%E5%AF%BE%E5%BF%9C%E3%82%A6%E3%82%A7%E3%83%96%E3%82%B5%E3%83%BC%E3%83%90 node.jsでSPDY対応ウェブサーバ] | ||
+ | * [[nginx]] | ||
+ | ** nginx 1.6ではSPDY 3.1に対応 | ||
+ | * Jetty 7.6.2と8.1.2以降 | ||
+ | |||
+ | == SPDYに対応したサーバにコマンドラインでアクセスする方法 == | ||
+ | [[SPDY]]に対応したサーバにコマンドでアクセスするには、[[spdylay]]で提供されるspdycatを利用します。curlコマンドライクにアクセスできます。 | ||
+ | <syntaxhighlight lang="bash"> | ||
+ | $ spdycat https://www.google.com/ | ||
+ | $ spdycat -v https://www.google.com/ | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === SPDYサーバにspdycatコマンドでアクセスする === | ||
+ | curlライクにSPDYに対応したサーバにアクセスする場合は、以下の通りです。 | ||
+ | <syntaxhighlight lang="bash"> | ||
+ | $ spdycat https://www.google.com/ | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | [[SPDY]]プロトコルの詳細を表示するには、-v オプションを使用します。 | ||
+ | <syntaxhighlight lang="bash"> | ||
+ | $ spdycat -v https://www.google.com/ | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Googleにアクセスした例です。SPDY 3.1 が選択されて通信が行われています。 | ||
+ | <syntaxhighlight lang="bash"> | ||
+ | $ spdycat -v https://www.google.co.jp/ | ||
+ | [ 0.038] NPN select next protocol: the remote server offers: | ||
+ | * spdy/5a1 | ||
+ | * h2-14 | ||
+ | * spdy/3.1 | ||
+ | * spdy/3 | ||
+ | * http/1.1 | ||
+ | NPN selected the protocol: spdy/3.1 | ||
+ | [ 0.053] Handshake complete | ||
+ | [ 0.053] recv SETTINGS frame <version=3, flags=0, length=20> | ||
+ | (niv=2) | ||
+ | [4(1):100] | ||
+ | [7(0):65536] | ||
+ | [ 0.054] recv WINDOW_UPDATE frame <version=3, flags=0, length=8> | ||
+ | (stream_id=0, delta_window_size=983040) | ||
+ | [ 0.054] send SYN_STREAM frame <version=3, flags=1, length=219> | ||
+ | (stream_id=1, assoc_stream_id=0, pri=3) | ||
+ | :host: www.google.co.jp | ||
+ | :method: GET | ||
+ | :path: / | ||
+ | :scheme: https | ||
+ | accept-encoding: gzip, deflate | ||
+ | user-agent: spdylay/1.3.1 | ||
+ | [ 0.124] recv SYN_REPLY frame <version=3, flags=0, length=578> | ||
+ | (stream_id=1) | ||
+ | :status: 200 OK | ||
+ | :version: HTTP/1.1 | ||
+ | alternate-protocol: 443:quic,p=0.01 | ||
+ | cache-control: private, max-age=0 | ||
+ | content-type: text/html; charset=Shift_JIS | ||
+ | date: Sun, 02 Nov 2014 05:10:31 GMT | ||
+ | expires: -1 | ||
+ | p3p: CP="This is not a P3P policy! | ||
+ | See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info." | ||
+ | server: gws | ||
+ | set-cookie: PREF=ID=XXXXXXXXXXXXXXXX:FF=0:TM=0000000000:LM=0000000000:S=XXXXXXXXXXXXXXXX; expires=T | ||
+ | ue, 01-Nov-2016 05:10:31 GMT; path=/; domain=.google.co.jp | ||
+ | set-cookie: NID=00=XXXXXXX; expires=Mon, 04-May-2015 05:10:31 GMT; path=/; domain=.google.co.jp; HttpOnly | ||
+ | x-frame-options: SAMEORIGIN | ||
+ | x-xss-protection: 1; mode=block | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == SPDYのバージョン == | ||
+ | === spdy/4 === | ||
+ | === spdy/3.1 === | ||
+ | * セッション単位のフロー制御が可能 | ||
+ | === spdy/2 === | ||
+ | === spdy/1 === | ||
+ | |||
== インストール == | == インストール == | ||
* [[Apache mod spdy]] | * [[Apache mod spdy]] | ||
+ | == ツール == | ||
+ | * [[spdylay]] | ||
== 関連項目 == | == 関連項目 == | ||
− | + | * [[HTTPS]] | |
− | <!-- vim: filetype=mediawiki --> | + | * [[TLS]] |
+ | <!-- vim: filetype=mediawiki | ||
+ | --> |
2014年11月15日 (土) 16:45時点における最新版
SPDY とは、HTTP 2.0の起草になった通信プロトコルです。SPDYを用いることで、ウェブページのロードを高速化できます。
読み方
- SPDY
- すぴーでぃー, えすぴーでぃーわい
目次
概要
HTTP/1系のプロトコルでは、仕様によりボトルネックを多く抱えていました。SPDYをセッションレイヤーに組み込むことにより、HTTPを速くします。
HTTPの通信のボトルネック
- 1回のコネクションにつき、1つのリクエストしか送信できない
- リクエストがクライアントからしか開始できない
- リクエストヘッダとレスポンスヘッダが圧縮できず、サイズが大きい
- ヘッダが冗長である
- データ圧縮が強制ではない
並列TCPコネクションの問題点
HTTP/1の実装のボトルネックの1つは、並列処理のためのTCPの複数のコネクションです。
- 接続により発生するラウンドトリップタイム
- スロースタート
- クライアントの1つのサーバに対する複数接続の制限
1 は、3ウェイ・ハンドシェイクのパケットの往復のことです。並列実行のために、このパケットがネットワークに流れます。
2 のスロースタートの問題は、TCPのウィンドウサイズが十分に大きくなるまでに時間がかかることです。ウィンドウサイズは、通信が進むにつれて、サイズが大きくなります。しかし、並列コネクションで通信する場合、ウィンドウサイズが十分に大きくなる前にデータの送受信が完了してしまいます。単一のコネクションで、ウィンドウサイズが大きい状態で通知んするほうがパケットの往復する数を減らすことができます。並列で接続している場合、それぞれのコネクションは、小さいウィンドウサイズで送受信することになるので、パケットの数が増えてしまいます。
3 は、サーバのコネクション(リソース)を使いきらないように、クライアントが1つのサーバあたりの接続性を抑制しているため、並列数が一定以上上げられない、ということになります。
HTTP 1.1
HTTP 1.0の問題がHTTP 1.1で解決されています。
- Keep Aliveにより、接続を使いまわすことができます。
- Keep Alive の問題は、同時に複数のリクエストが送信できないことです。現在送信中のHTTPリクエストに対するHTTPのレスポンスが返ってくるまで、次のリクエストが送信できません。
- アクセスの多いサイトでは、Keep Aliveをオンにしていると接続を使いきってしまい、新しく接続してきたクライアントの接続を受け入れられなくなるため、十分なリソースがないと Keep Alive が使えないケースがあります。
piplining
pipliningは、HTTPレスポンスの受信の失敗や受信の遅延により、pipline上の他のHTTPリクエストやレスポンスの送受信が失敗か、遅延を引き起こしてしまいます。 並列のリクエストのいずれかが失敗すると、TCPコネクションの接続確立からやり直す必要があります。
SPDYの特徴
- SPDYは、バイナリプロトコルであるため、HTTPヘッダデータのサイズを小さくできます。
- ストリームベースの多重化により、GETに対して、コンテンツを複数並列で返すことができます。
- クライアントは、リクエストに優先度がつけられます。
- ヘッダは、デフォルトで圧縮され、不要なヘッダは削除されます。
- コンテンツをブラウザにキャッシュし、ヒットしないときだけサーバに取りに行きます。
- サーバプッシュ通信をサポートします。
SPDYでは、TCPコネクション上に複数の論理的なストリームを構築します。それぞれのストリームは独立し、リクエストの順番とレスポンスの順番に制約はありません。
ストリームの制御には、データを含まない専用のコントロールフレームを用います。それぞれのコントロールフレームは、Stream-IDを持ち、このIDにより、各ストリームは区別されます。
データ本体は、データフレームとして送信されます。
SPDYは、ストリームのライフサイクルの管理のために3つのコントロールフレームを定義しています。
- SYN_STREAM
- 新しいストリームを開きます。
- SYN_REPLY
- リモートアックノレッジメント
- RST_STREAM
- ストリームを閉じます。
ネットワークの層とプロトコルの対応
SPDYは、セッション層にあたります。
層 | プロトコル |
---|---|
アプリケーション層 | HTTP |
セッション層 | SPDY |
プレゼンテーション層 | SSL |
トランスポート層 | TCP |
SPDYの環境
SPDYを使用するには、SPDYに対応したWebサーバとウェブブラウザが必要です。 ChromeやFirefoxなどのブラウザは、SPDYに対応しています。 Apache HTTP Serverは、 Apache mod spdyを組み込むことで利用できます。
SPDYに対応しているWebサーバ, プロキシ を挙げます。
- Apache HTTP Server(httpd) - Apache mod spdy
- Apache Traffic Server(ATS), プロキシ
- node.js spdyモジュール
- sudo node install -g spdy
- node.jsでSPDY対応ウェブサーバ
- nginx
- nginx 1.6ではSPDY 3.1に対応
- Jetty 7.6.2と8.1.2以降
SPDYに対応したサーバにコマンドラインでアクセスする方法
SPDYに対応したサーバにコマンドでアクセスするには、spdylayで提供されるspdycatを利用します。curlコマンドライクにアクセスできます。
$ spdycat https://www.google.com/ $ spdycat -v https://www.google.com/
SPDYサーバにspdycatコマンドでアクセスする
curlライクにSPDYに対応したサーバにアクセスする場合は、以下の通りです。
$ spdycat https://www.google.com/
SPDYプロトコルの詳細を表示するには、-v オプションを使用します。
$ spdycat -v https://www.google.com/
Googleにアクセスした例です。SPDY 3.1 が選択されて通信が行われています。
$ spdycat -v https://www.google.co.jp/ [ 0.038] NPN select next protocol: the remote server offers: * spdy/5a1 * h2-14 * spdy/3.1 * spdy/3 * http/1.1 NPN selected the protocol: spdy/3.1 [ 0.053] Handshake complete [ 0.053] recv SETTINGS frame <version=3, flags=0, length=20> (niv=2) [4(1):100] [7(0):65536] [ 0.054] recv WINDOW_UPDATE frame <version=3, flags=0, length=8> (stream_id=0, delta_window_size=983040) [ 0.054] send SYN_STREAM frame <version=3, flags=1, length=219> (stream_id=1, assoc_stream_id=0, pri=3) :host: www.google.co.jp :method: GET :path: / :scheme: https accept-encoding: gzip, deflate user-agent: spdylay/1.3.1 [ 0.124] recv SYN_REPLY frame <version=3, flags=0, length=578> (stream_id=1) :status: 200 OK :version: HTTP/1.1 alternate-protocol: 443:quic,p=0.01 cache-control: private, max-age=0 content-type: text/html; charset=Shift_JIS date: Sun, 02 Nov 2014 05:10:31 GMT expires: -1 p3p: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info." server: gws set-cookie: PREF=ID=XXXXXXXXXXXXXXXX:FF=0:TM=0000000000:LM=0000000000:S=XXXXXXXXXXXXXXXX; expires=T ue, 01-Nov-2016 05:10:31 GMT; path=/; domain=.google.co.jp set-cookie: NID=00=XXXXXXX; expires=Mon, 04-May-2015 05:10:31 GMT; path=/; domain=.google.co.jp; HttpOnly x-frame-options: SAMEORIGIN x-xss-protection: 1; mode=block
SPDYのバージョン
spdy/4
spdy/3.1
- セッション単位のフロー制御が可能