SPDY

2012年06月16日

SPDY on nginx!!

今日spdy-devのMLに「nginxでspdy対応したよ!!」がPOSTされたので、早速 share

1.3.xへのパッチとして提供されています。インストール方法などは以下のURLをチェックしてみてください。

http://nginx.org/patches/spdy/README.txt

僕まだ試せていませんが、nginxが対応するとテンション上がりますよねw いやホントSPDY熱いっす。


P.S. 来週 App Engine ja nightでSPDYについて講演します。


人気ブログランキングへ
kotesaki at 00:50|PermalinkComments(19)TrackBack(0)clip!

2012年06月03日

GAE で作ろう!! 簡単にSPDY対応サイト

最近、大台の40になったということで、健康に気を付けようかな・・・と毎週末近所の河川敷をジョギングしています。初めてから大体一ヶ月、最初は 4km 走ったら筋肉痛でとんでもないことになっていましたが、最近は 7km ぐらいを 6min./km ぐらいのペースで走れるようになりました。とりあえず、1年後ぐらいにはどこかのマラソンに出るぐらいの目標で頑張ろうかなと思っています。

さて今日は Google の PaaS サービス、GAE (Goole App Engine)で、SPDYを簡単に使えますという話です。
1

SPDY indicator

突然ですが、WebサイトがSPDYに対応しているかを簡単にチェックするものとして、SPDY indicator というツールがあります。Chrome Extension や、FireFox Add-onsとして公開されています。 
2
これをインストールすると、SPDY対応サイトではアドレスバーの右端に緑色のアイコンが表示されます。「へぇーこのサイトSPDY対応なんだw」とほくそ笑むだけの Geeky なツールですが、なかなか楽しいです。SPDY好きの人にはオススメです。
3

GAE spdy対応してんじゃん!!

で、先日とあるプレゼン資料準備のため、WebRTCのデモサイトを見ていたときのこと。ふと画面右上を見ると、そこには煌々と輝く緑色のアイコンが!!僕は、これを見て興奮してしまいました。
4
というのも、このサイト GAE 上で公開されています。ってことは、Google App Engine が SPDY 対応してるってこと。つまり、GAE使えば誰でも簡単にSPDY対応サイトが作れる!!ってことに他なりません。これは、素晴らしい!!

前回の記事でも述べましたが、SPDYの特徴の一つは、その簡単さ。ApacheとかnginxのようなフロントエンドのミドルウェアがSPDY対応すれば、それだけでOKです。HTML/CSS/JavaScriptは何も変更する必要がありません。てことは、上のデモがSPDYで動いているってことは、GAEのフロントエンド(もちろん、何を使っているかは知りませんが・・・)がSPDY対応していることに他なりません。つまりふつーにGAEでdeployして、プロトコルスキーマとしてhttpsを指定すればSPDY対応サイトになる!!とゆーことになるわけです(これまでGAEで公開していたサイトも含め全て)。
5

Channel APIは?

といったことで、最初FaceBookで盛り上がっていたら、@kazunori_279さんから、早速「Channel APIはどうでしょう?」という質問が。なるほど、確かに気になります。SPDYは、基本的にフロントエンドが対応していればOKな技術ですし、現在のChannel APIは Comet をベースにしています。なので、この Comet に使っているURL(フロントエンド)がSPDYに対応していれば、特段 Channel API 側で特別な対応をしていなくてもOKということに。調べてみる価値おおいにあり。

ここで、先程のWebRTCのデモでは、ピアのセッション情報の交換に Channel API を使っています。で、調べてみるとSDPデータの送信には、https://apprtc.appspot.com/... を使い、Push受信には https://906.talkgadget.google.com/... を使っていました(906の部分は、ころころ変わります)。で、これらのセッションを chrome://net-internals/#spdy で見てみると、どちらもSPDYを使っている様子。てことで、Channel APIも含め SPDY に対応していることが分かりました。
6

僕も作ってみた

ということで、僕も早速以前のブログで紹介した、SPDYの速度比較デモを GAE に deployしてみました。といっても、単に以前作っていた HTML/CSS/JavaScript をそのまま使うだけですので、チョー簡単です。https://spdykomtest.appspot.com/pub/test.htmlでhttpsをプロトコルスキーマとして指定してChromeやFireFox13以上でアクセスすれば SPDY で動きますし、http://spdykomtest.appspot.com/pub/test.htmlとhttpを指定すれば非SPDYで動きます。どれぐらいの速度差がでるかはそれぞれの環境次第ですが、是非お試しを
7

まとめ

ということで、GAE 使えば簡単に SPDY 対応サイト deploy できるよ!!というレポートでした。特別なセットアップしなくても、GAEでふつーにDeployを行うだけでSPDYが使えるというのは嬉しい限り。公開するときに、プロトコルスキーマを"https"にするだけですもんね!!なお、今回のテクニックですが、appspot.com のドメインを使っている場合の話ですので、そこは注意ください。オリジナルドメインを当てている場合、証明書の関係からだと思いますが SPDY にはなりません。専用のドメインにしている場合、証明書をきちんとあてればSPDYになるんでしょうか。。。ごめんなさい、そこまでは調べきれていません。このあたりのことを知っている方いらっしゃいましたら、是非コメントなりTBなり頂けると嬉しいです。


Google App Engineプログラミング入門
人気ブログランキングへ
kotesaki at 14:59|PermalinkComments(51)TrackBack(0)clip!

2012年05月04日

node-spdy 試してみた

今日のブログのお題は、SPDY。Webサービスを「とにかく速くしよう!!」ということで、Google が提唱したプロトコルです。既にChromeでは、このSPDYが実装されており、サーチやGMailなど Google が提供する殆どのサービスで既に利用されています。

最近では、FireFoxへのインプリが始まったり、HTTP/2.0検討のベースとなるなど何かと話題のWeb最新技術です。

SPDYがWebを早くする仕組み

SPDYは、現状のWebが抱える問題 ”HTTPは遅い!!" を解決するものです。HTTP が "遅い" 原因は色々ありますが、中でも最も大きいのは Request and Response の制限です。このため、SPDY では一本の HTTPS セッションの中で複数の HTTP セッションを多重化するといったことを行い高速化を実現しています。

Request & Responseの制限

Request and Responseの制限とは、一本の HTTP セッションでは先に送った Request に対する Response が返ってこないと次のRequestが送れないという制限です。このResponseを待っている時間(RTT : Round Trip Time) ブラウザとサーバーとの通信が待たされる、行えない。なので、ダウンロードするファイル(javascript や画像など)が増えるとどうしても読み込み時間がかかってしまうという構造的な問題をはらんでいます。

1

従来の高速化プラクティス〜HTTPセッションの複数利用〜

この速度低下を防ぐため、通常ブラウザでは複数のHTTPセッションを同時に利用します。他のセッションであれば、上述の制限は受けないため、下図に示すように読み込み時間を飛躍的に短縮することができます。

2

従来プラクティスの問題点

このように、HTTPセッションを複数同時利用すればWebサイトのファイル読み込み時間を短縮し、ユーザー体験を向上することができます。しかしながら、この解決策には
サーバーやNW機器の負荷を増大してしまう という問題があります。これらの機器ではセッション数が増えるとCPU負荷やメモリが増えてしまいます。従って、システムのコストを抑えるためにはセッション数をなるべく少なくするのが望ましいことになります。このため、HTTP/1.1仕様(RFC2616)の"8.1.4 Practical Considerations"では

A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy. (中略) These guidelines are intended to improve HTTP response times and avoid congestion.
と記述されています。ざっくり訳すと「同時セッション数は2とすべきである。これは HTTP の response time を改善するとともに、輻輳を避けるためのガイドラインです」といったところでしょう。このガイドラインに則ると、読み込み時間は大体2分の1程度になると見積もれます。このため、ブラウザでは同一サーバーに対する同時HTTPセッション数に制限をかけるという実装を行っています。

ただし、この 2 セッション という制限は、あまりにお行儀のよい数字であり、かつ近年のWebサイトあたりのファイル数の増加トレンドにそぐわないということで、最近のブラウザでは6セッション程度にこの値を緩和しています(ブラウザ依存)。

ただし、例えば6セッションで読み込み速度を最大まで短縮できるかというと、不十分な場合が殆どです。これを嫌いFQDNを分散するなど様々なハックが使われたりしますが、これでは先にあげたサーバーやNWの負荷を増大してしまいます(サービス提供コストが高くなってしまう)。なんとか、1セッションで制限を受けること無く、複数のファイルに対するリクエストをカバーしたいところです。

SPDYによる高速化

このためSPDYでは 1 本のHTTPSセッションの上で、複数の Request を多重化するというアプローチを採用しています。これにより先ほどあげた課題は解決され、高速かつシステムコストの低減が実現されます。また、それ以外にも様々な高速化のアプローチがなされており、トラフィックを下げるために HTTP ヘッダーを圧縮するといったことが行われています。

3

WebSocketとの違いは?

僕の以前のブログ記事「websocketでpipelineをすると、感動的に早い!! 」(ちなみに、最近このわかちサイトはhttp://wakachi.komasshu.info/に移動しています)を読まれたことのある方は混乱しているかもしれません。「複数の request を 1 セッションで多重化する」のは WebSocket で実現されるんじゃないの?というものです。確かにその通りですし、アプローチの基本的な考え方は、WebSocketで多重リクエストを投げるのも SPDY を使うのも大差ありません。

決定的な違いは、ざっくり言うと SPDY を使ったほうが圧倒的に簡単という点。 WebSocket で多重通信を行うにはそれ用のコードをJavascript でコーディングしなければならず、かつサーバー側でも専用のアプリケーションを書く必要があります。既存サイトへの改変コストは馬鹿になりません。一方、SPDYでは Javascript の追加コーディングが必要ありません。基本的には、既存のHTMLなどを、そのままSPDYサーバーにアップロードするだけでOK。
対応ブラウザを利用しているユーザーにはSPDYを用いた高速なユーザー体験を、非対応ブラウザ利用者には従来のHTTPSでそのままサービスが提供されます。
なので、ファイルダウンロードの高速化を図りたいなら SPDY を利用。双方向アプリケーションでプログラミングが要求されるときは WebSocket を利用というのがこれからの Best Practice なんじゃないかなと思います。

執筆時点の対応ブラウザは Chrome と Firefox のみ(FF13よりデフォルトでSPDYがenableに)ですが、両ブラウザの合算シェアは Worldwide で 50% 以上、日本でも 35 % ( StatCounterより)となっており、サーバーを変えるだけでこれだけの割合のユーザーに高速なサービスを提供できるのは魅力的な話です。余談ですが、現状の SPDY は HTTPS の上で動いていますが、マイクロソフトから WebSocketの上で動くSPDYがIETFで提案 されています。ということは、ゆくゆくはIEも。。。というのが期待できます。Googleでは殆どのサービスで既に使われていますし、実績もある。検討の価値大有りですよね。

4

node-spdy

ということで、本題の SPDY の使い方です。Apache用のSPDYモジュール mod_spdyが公開されており、こちらを使うのが簡単そう(多分、HTTPS対応のApacheにこのモジュールを追加するだけ)ではあるのです。今回は"プログラミング的な観点で触ってみたい"ということで、SPDYのnode実装node-spdyをトライしてみました。なお、SPDYのプロジェクトページには様々な環境での SPDY 実装やライブラリのリンクがありますので、興味のある方はこちらも確認してみてください。

node 0.7.x のインストール

まず、node-spdyですが zlib のサポートの絡みから現在の公開バージョン(0.6.x)では動作せず、Experimental バージョンの 0.7.x を使う必要があります。インストール方法は、以下の通り。

git clone git://github.com/joyent/node.git
cd node
./configure --prefix=$HOME/.node/dev

make install -j2 # jの後の数字はマシンのCPUコア数
                 # 筆者環境では2コアのマシンを用いたため 2 とした
これで、~/.node/dev/bin配下に node や npm がインストールされます。パスを通してもいいのですが、現状expressが使えないなど何かと面倒なので、SPDY 試すときだけ絶対パス直打ちという男な感じで今回はやってみることにしました。

まずは試してみる

まずは簡単に試してみようということで、node-spdyのreadmeに書かれているサンプルコードを参考に、以下のようなコードを書いてみました。

package.json
{
  "name": "application-name"
  , "version": "0.0.1"
  , "private": true
  , "dependencies": {
    "spdy": ""
  }
}
app.js
var spdy = require('spdy'),
  fs = require('fs');

var options = {
  key: fs.readFileSync(__dirname + '/keys/spdy-key.pem'),
  cert: fs.readFileSync(__dirname + '/keys/spdy-cert.pem'),
  ca: fs.readFileSync(__dirname + '/keys/spdy-csr.pem')
};

var server = spdy.createServer(options, function(req, res) {
  // Displays current transfer mode
  var mesg_ = req.isSpdy ? "Hello SPDY!" : "Hello HTTPS"
  res.writeHead(200);

  res.end(mesg_);
}

server.listen(10001);
spdyのライブラリをrequireして、optionsで証明書系のファイルを指定(サンプルの証明書類は https://github.com/indutny/node-spdy/tree/master/keys から入手するのが簡単)。あとは、createServer()メソッドを呼ぶだけで、コード自体は通常のHTTPServerを書く場合と大差ありません。(isSpdyプロパティを見ると、SPDYでアクセスされているかどうか判定できるので、上のコードではメッセージを変えるようにしてみました)

で、

~/.node/dev/bin/npm install
~/.node/dev/bin/node app.js
としてやれば、https://localhost:10001 でアクセスできます。このサイトは、https://komasshu.info:10001/で公開しています。SPDY対応ブラウザでアクセスすると"Hello SPDY!"と、非対応ブラウザでアクセスすると "Hello HTTPS"と表示されます。
5

"Speed"を体験してみよう

上のままではつまらないので、速度体験サイトを作ってみました。

SPDY速度体験サイト
https://komasshu.info:10001/test.html
6
start ボタンをクリックすると150個のアイコンがダウンロードされ、そのダウンロード時間が表示されるといういたってシンプルなもの。本当は express を使いたかったのですが、node-0.7.xでは現状 express が上手く動かないため、ファイルのハンドリングを素でコーディングしました。コードの全体は https://github.com/KensakuKOMATSU/spdy_test で公開していますので、興味のある方は確認してみてください(大したことは一切やっていません)

node-spdyは、ブラウザの対応状況に応じて、自動で SPDY と通常のHTTPSをスイッチしてくれます。で、非対応ブラウザ(OperaやFF12のデフォルト設定)で試してみたところ僕の環境で大体 1.2 秒ぐらいかかったのですが、SPDY対応ブラウザ(Chrome20でtry)で試してみると 200 msec という結果が得られました。かなりの速度向上です。ちなみに、MacのSafari5で試したら非対応ブラウザにも関わらず 300 msec というSPDYにひけをとらない数値が得られました。きちんと調べていないのでアレですが、Safari5では同時セッション数の制限が緩いのかもしれません。

ちなみに、同様のことをWebSocketでトライ出来るサイトをhttp://komasshu.info:3000/で公開しています(Chrome or FFでのみ動作。WebSocketのバイナリーモードサポートブラウザでのみ)。こちらと比較すると、WebSocketよりSPDYのほうが若干ですが早い結果が僕の環境では得られました(方式的な差というより、実装上の差なんじゃないかなと思っています)。いずれにしろ、SPDY凄いですね!!

さて、今回紹介した SPDY ですが一点注意点があります。それは、HTTPS を使っているためプロキシなどでキャッシュされないこと。なので、画像やスタティックなコンテンツもSPDYで提供しようとすると、逆に速度低下になりかねないということです。なので、現状HTTPSで提供している「動的コンテンツ」「途中でキャッシュされたくないファイル」であれば SPDY 検討の価値がある一方、「途中でキャッシュされると嬉しい静的なサイト」では逆効果になりかねませんので、その点はご注意ください。


人気ブログランキングへ
kotesaki at 21:59|PermalinkComments(8)TrackBack(1)clip!