次世代プロトコル「SPDY」

cloud
2013/07/14

はじめに

ふらっと本屋に立ち寄ってウェブDBプレスのHTTP/2.0の特集が目に止まったので早速購入!
ということで、記事のサマリをご紹介します。
さらに興味がある方は是非購入下さい。

概要

「SPDY(スピーディー)」とは、Googleのエンジニアが開発したWebのパフォーマンス改善を目的としたプロトコルです。
このプロトコルはGoogleのサービスはもちろんのこと、Facebook、Twitter、LINEも対応を始めているそうです。
また、HTTP/2.0の仕様のベースは「SPDY」が採用されたようです。

なぜGoogleは独自プロトコルのSPDYを用いてサービス展開できたのかというと、Chromeさんを持ってたから可能だったようです。
たしかに、クライアントソフトを自社開発していれば、独自プロトコルにしても全然問題ないですね。

HTTP/1.0の特徴

Webの初期の目的はネットワーク上で文書を共有することでした。
HTTPでこの仕組みを実現できれば良かったわけですね。
今見たいなリッチクライアントだとか、数万規模のアクセスを実現するような技術的要求は無かったわけです。

HTTP/1.0の特徴は以下の点にあります。

・TCP接続時の3-way-handshake
クライアントがリクエストを投げるためのTCP接続のためにサーバと3回やりとりをします。 これはリクエストが発生する度に行います。

・TCP通信時の輻輳制御
一度に大量のデータを送信して通信が成立しなくなるのを防止するため、尻上がりに送信できるデータ量が増やしていきます。
これはTCP接続が切断されるとリセットされます。

HTTP/1.1の特徴

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で確立するとサーバが耐えられなくなる可能性あり
・確立した接続が通信していないのに残ったままになる場合有り
・同時に送信するリソースの上限やタイムアウトの適切な設定が必要になる

TCP接続

SPDYもトランスポート層にTCPを利用しています。SPDYではサーバとTCP接続を一度確立すると、 それを複数のリクエスト/レスポンスで使いまわします。
これにより、従来のHTTPのようなKeep-Alive+パイプライン化と同様の効果を生み出します。
異なる点は、リクエスト/レスポンスが全て多重化しているため、同時にいくつでもリクエストを 投げることができ、従来の規約にはないレスポンスの順序も自分で設定することができるようになりました。
遅くて優先順位の低いレスポンスは後回しにするという工夫ができますね。

TLS(Transport Layer Security)

SPDYはセッション層でTLSを利用することが前提となっています。そのため、URLはHTTPSから始まり、 SSLの証明書が必要になります。 なぜTLSが必要になるのか。それは、TLSの拡張のNPNという仕組みを使っているからです。 NPNは何者か?これを使うことで、接続確立時にSPDYを使うのか、HTTPを使うのかを選択することができます。 クライアントかサーバがSPDYに対応していない場合、HTTPを採用するというようなことができますね。

フレーム

HTTPメソッド、ステータスコード、などのヘッダ情報やボディ情報はSPDYのフレームに含めて送受信できるため、 従来のアプリケーションの移行は比較的難しくないと言えます。

Server Push

HTTPはPull型のプロトコルでしたが、SPDYはリソースをサーバからPushする仕組みを採用しています。
これにより、リクエストされていないリソースをサーバから事前にクライアントへ送信することができます。
例えば、HTMLのレスポンスをクライアントが待つ前に、JSやCSSなどを事前にPushし、クライアントのキャッシュに保存します。 それにより、HTMLのレスポンスをクライアントが受け取ると、JSやCSSのリクエストをサーバに問い合わせる前に キャッシュにヒットするためクライアントはサーバへアクセスする必要が無くなります。

ストリームの優先度

SPDYではリクエスト/レスポンスごとに1つの論理的な接続を確立します(ストリームの生成)。
ストリームは多重化されているため、順序の依存関係がありません。それにより、リクエストした順でなくても レスポンスを返すことが可能です。 しかし、順不同なため、不都合が生じる場合があるかと思います。そこで、ストリームに優先度をつけることで クライアントの欲しい順にサーバが返すことが可能です。

WebSocketとSPDYの違い

私もそうだったのですが、「Server PushってWebSocketて同じじゃね?」と思っていました。 この記事を読んで納得しました。違いはそもそもの目的にありました。

WebSocket:サーバとの通信をより柔軟に行う
→動的なコンテンツの通信が可能

SPDY:コンテンツのやりとりを効率良く行う
→静的なコンテンツの通信を想定

以上がSPDYの特徴になります。

このSPDYの仕様をベースにHTML/2.0が出来上がりそうですので、Webエンジニアは是非押さえておきたい話だと思います。 詳しい説明につきましては、ウェブDBプレスをご一読下さい。

※内容に誤りなどありましたらごめんなさい。。。

  • このエントリーをはてなブックマークに追加
Related

PHPで動画の撮影日を取得

PHPで動画の撮影日を取得 概要 PHPからffprobeコマンドを実行し、動画の撮影日時を取得します。 コード $posted_at = ...

FullCalendarでGoogleカレンダーのようなUIを実装

jQueryプラグインFullCalendarのサンプル 概要 FullCalendarを使用して、GoogleカレンダーのようなUIを実装する使用例を...

PHP Laravel5.2でmulti-auth(複数テーブルでの認証)を実装

Laravel5.2でマルチ認証 概要 LaravelとはPHPの中で今最も伸びているフレームワークです。 処理速度が遅いなどありますが、かなり使い安く拡...

PHP 正規表現でIPアドレス形式の文字列か判定

正規表現でIPアドレスの入力チェック 概要 フォームで入力されたIPアドレスが正当な文字列か判定するためのバリデーション処理を実装します。 基本的...

rbenv環境でRuby on Railsのアプリケーションを一瞬で自動生成

アプリケーション構築時に最初に行う手順 概要 アプリケーションを作成するまでの手順を記載しています。 rbenvなどの環境が設定済と仮定して話を進めま...

Rails devise・authority・rolifyで権限付きの認証機能

devise・authority・rolify 概要 3つのGemを使用して、権限付き認証機能を実装します。 gem インストール Gemfile ...
トップへ戻る