ふらっと本屋に立ち寄ってウェブDBプレスのHTTP/2.0の特集が目に止まったので早速購入! ということで、記事のサマリをご紹介します。 さらに興味がある方は是非購入下さい。
「SPDY(スピーディー)」とは、Googleのエンジニアが開発したWebのパフォーマンス改善を目的としたプロトコルです。 このプロトコルはGoogleのサービスはもちろんのこと、Facebook、Twitter、LINEも対応を始めているそうです。 また、HTTP/2.0の仕様のベースは「SPDY」が採用されたようです。
なぜGoogleは独自プロトコルのSPDYを用いてサービス展開できたのかというと、Chromeさんを持ってたから可能だったようです。 たしかに、クライアントソフトを自社開発していれば、独自プロトコルにしても全然問題ないですね。
Webの初期の目的はネットワーク上で文書を共有することでした。 HTTPでこの仕組みを実現できれば良かったわけですね。 今見たいなリッチクライアントだとか、数万規模のアクセスを実現するような技術的要求は無かったわけです。
HTTP/1.0の特徴は以下の点にあります。
・TCP接続時の3-way-handshake クライアントがリクエストを投げるためのTCP接続のためにサーバと3回やりとりをします。 これはリクエストが発生する度に行います。
・TCP通信時の輻輳制御 一度に大量のデータを送信して通信が成立しなくなるのを防止するため、尻上がりに送信できるデータ量が増やしていきます。 これはTCP接続が切断されるとリセットされます。
3-way-handshakeや輻輳制御によるボトルネックを軽減させる仕組みが提供されています。
・Keep-Alive この機能を有効にすると、一度確立したTCP接続を複数回のリクエスト/レスポンス間で使いまわすことができます。 これにより、3-way-handshakeの実施回数の減少や、送信できるデータ量がリセットされないため、レスポンスも向上します。 でもこれだけでは高速化としては不十分。 なぜなら、HTTP/1.0では「先行するリクエストに対するレスポンスが完了するまで、 次のリクエストを発行してはならない。」というなんとも融通のきかない規約があります。 そのため、Keep-Aliveを有効にしたところで、最初のリクエストに対するレスポンスがめちゃ時間が掛かると 後続のリクエストが投げられないわけですorz
・パイプライン化 上記の問題を解決するのが、パイプライン化です。 HTTP/1.1から「Keep-Aliveが有効な接続上ではパイプライン化が可能である。」という仕様が定義されました。 パイプライン化とは、リクエストはレスポンス待たずにどんどん投げれるよ!というものです。 しかし、レスポンスはリクエストと同じ順で返していきます。。 つまり、パイプライン化をしたところで、先頭のレスポンスが遅ければ後続のレスポンスも遅くなるわけですorz
・Accept-Encoding HTTPはテキストベースのプロトコルです。 リクエスト/レスポンスのヘッダは全てテキストデータのため、パケットサイズが大きくなります。 HTTP/1.1ではヘッダにAccept-Encodingを定義することにより、サーバから圧縮したレスポンスが受信可能になります。 転送効率は向上します。しかし、リクエストの圧縮はできません。。
あと、Keep-Aliveやパイプライン化はいくつかの課題があります。 ・パイプライン化非対応のサイトでパイプライン有効なクライアントから接続すると表示が崩れる ・複数のTCP接続をKeep-Aliveで確立するとサーバが耐えられなくなる可能性あり ・確立した接続が通信していないのに残ったままになる場合有り ・同時に送信するリソースの上限やタイムアウトの適切な設定が必要になる
SPDYもトランスポート層にTCPを利用しています。SPDYではサーバとTCP接続を一度確立すると、 それを複数のリクエスト/レスポンスで使いまわします。
これにより、従来のHTTPのようなKeep-Alive+パイプライン化と同様の効果を生み出します。
異なる点は、リクエスト/レスポンスが全て多重化しているため、同時にいくつでもリクエストを 投げることができ、従来の規約にはないレスポンスの順序も自分で設定することができるようになりました。
遅くて優先順位の低いレスポンスは後回しにするという工夫ができますね。
SPDYはセッション層でTLSを利用することが前提となっています。そのため、URLはHTTPSから始まり、 SSLの証明書が必要になります。 なぜTLSが必要になるのか。それは、TLSの拡張のNPNという仕組みを使っているからです。 NPNは何者か?これを使うことで、接続確立時にSPDYを使うのか、HTTPを使うのかを選択することができます。 クライアントかサーバがSPDYに対応していない場合、HTTPを採用するというようなことができますね。
HTTPメソッド、ステータスコード、などのヘッダ情報やボディ情報はSPDYのフレームに含めて送受信できるため、 従来のアプリケーションの移行は比較的難しくないと言えます。
HTTPはPull型のプロトコルでしたが、SPDYはリソースをサーバからPushする仕組みを採用しています。
これにより、リクエストされていないリソースをサーバから事前にクライアントへ送信することができます。
例えば、HTMLのレスポンスをクライアントが待つ前に、JSやCSSなどを事前にPushし、クライアントのキャッシュに保存します。 それにより、HTMLのレスポンスをクライアントが受け取ると、JSやCSSのリクエストをサーバに問い合わせる前に キャッシュにヒットするためクライアントはサーバへアクセスする必要が無くなります。
SPDYではリクエスト/レスポンスごとに1つの論理的な接続を確立します(ストリームの生成)。
ストリームは多重化されているため、順序の依存関係がありません。それにより、リクエストした順でなくても レスポンスを返すことが可能です。 しかし、順不同なため、不都合が生じる場合があるかと思います。そこで、ストリームに優先度をつけることで クライアントの欲しい順にサーバが返すことが可能です。
私もそうだったのですが、「Server PushってWebSocketて同じじゃね?」と思っていました。 この記事を読んで納得しました。違いはそもそもの目的にありました。
WebSocket:サーバとの通信をより柔軟に行う
→動的なコンテンツの通信が可能
SPDY:コンテンツのやりとりを効率良く行う
→静的なコンテンツの通信を想定
以上がSPDYの特徴になります。
このSPDYの仕様をベースにHTML/2.0が出来上がりそうですので、Webエンジニアは是非押さえておきたい話だと思います。 詳しい説明につきましては、ウェブDBプレスをご一読下さい。
※内容に誤りなどありましたらごめんなさい。。。