ぼちぼち日記

おそらくプロトコルネタを書いていることが多いんじゃないかと思います。

これはChrome Turbo?Google Silk? AndroidでSPDYを使ったData Compression Proxyを試す

1. はじめに、

本日早朝、AndroidChrome のベータ版がアップデートし、バージョン26になりました。
それに伴い、Googleより Chrome の SPDY Proxyの機能と、Googleが提供する Page Speed サービスを組み合わせたData Compression Proxy という実験サービスのアナウンスがあり、早速使っていろいろ調べてみました。

2. Data Compression Proxyとは何?

このData Compression Proxyはどういうものでしょうか?
Googleの案内ページに記載されている下記の図が一番わかりやすいです
https://developers.google.com/chrome/mobile/images/spdy-proxy.png

Andoroid端末からData Compression Proxyを有効化したChrome(ベータ版)を使ってWebページにアクセスをすると、

  • HTTPSは、これまで通りAndroid端末から直接サーバへアクセスする。
  • HTTPは、一度 Google が用意するProxyサーバを経由してサーバにアクセスをする。
    • Android端末のChromeは、SPDY Proxy機能を使って、ProxyサーバとSPDY接続をする。
    • Proxyサーバでは、Android端末からリクエストを受けたコンテンツを対象サーバから取得し、PageSpeed 技術を使ってデータ量を減らしたコンテンツをクライアントに返します。Proxyサーバ内ではコンテンツのキャッシュも行なわれます。

といったことが実現できます。

上記のPage Speedは、コンテンツの無駄な部分を削除や圧縮、低容量の画像フォーマットへの変換などを行う機能です。Googleは、これまでも「Turbocharge your web site with Google's PageSpeed Service」というリバースProxyの試験サービスを提供していますが、今回はこれと同様のフォワードProxy相当のものだと思われます(おそらくAndroid端末向けにコンテンツ圧縮の最適化が行われているでしょう)。

SPDY Proxy機能は、以前からデスクトップ版でも提供されていた機能です(SPDY & Secure Proxy Support in Google Chrome)。 受ける側のProxyサーバも、Node.jsで作った試験的な実装、(node-spdyproxy)が公開されています。今回、このProxy機能に、PageSpeed+キャッシュ管理機能をつけてGoogleがサービスを提供し始めた、と捉えればよいでしょう(さすがにNodeを使っているとは思えませんが)。

過去、同様の機能が Amazon SilkOpera TurboSPDY support for Turbo) で実現されていました。 今回、この Google Chrome版が出たと言えます。

3. Chrome Beta for Android の SPDY Proxyを使う

では早速使ってみましょう。現在最新の Chrome Beta for Android (26.0.1410.26) をインストールしてみます。
chrome://flags で下記の通り Data Compression Proxy の機能を有効すると使えます。

いくつかHTTPのページを閲覧して、chrome://net-internals/#spdy を見てみます。

flywheel.ext.google.com 宛にSPDYセッションが張られています。このサーバ(flywheel.ext.google.com)が、 Data Compression Proxy です。

PageSpeed でどれだけデータが圧縮されているしょうか? それは、chrome://net-internals/#bandwidth で見ることができます。


各項目は、オリジナルのコンテンツの容量、実際に受け取った容量、Data Compression Proxyで減ったデータ量、Data Compression Proxyで減ったデータの割合を表します。

これによると、上記の場合一つの接続でなんと72.6%も受信データ量を減らすことができたのです。Data Compression Proxyを経由するとオリジナルのデータ量のほぼ1/4まで圧縮されるとは驚きです(Webp の技術詳細はまだ不勉強で知らないのですが、きっとそのおかげなんでしょうね)。

4. どんな感じで動いているのかな?

では、どんな感じで動いているのか、サーバ側、クライアント側からデータを覗いて探ってみましょう。 ある画像データのHTTPサーバ側のパケットダンプを取得しました。


HTTPサーバへアクセスするクライアントIPは、当然GoogleのサーバのIPになっています。その替り X-Forwarded-For のヘッダに実際のクライアントのIPアドレスが記載されています。サーバから返したレスポンスのうち、青下線の部分が後で書き換えられちゃう部分です。

今度はクライアント側で受信した同じ画像ファイルのキャッシュデータからレスポンスヘッダを見てみます。

Google Proxy を経由することで、Content-Typeが jpeg から webp に変わっています(当然画像データのフォーマットもWebpに変わっているはず)。それに伴い、 Content-Length, Etagも変更されています。そして新たに cache-control, vary, x-origin-content-length のヘッダが付与されています。Google側からクライアントに指定させるコンテンツキャッシュ時間はデフォルトで30分の様です。

新たに付けられた -origin-content-length は、サーバ側で送った content-length と一致しますので、きっとこれがオリジナルのデータ容量を表すものでしょう。先ほどの bandwidth の統計情報は、このクライアント側で受信した content-length と x-origin-content-length の値の統計を取ったものと思われます。

いろいろ試してサーバ側で確認すると、Google Proxyサーバ側がコンテンツキャッシュを保持している間は、HTTPサーバ側に etag の変更を確認しに来るようです。一度キャッシュされると、当分 HTTPサーバ側が 304(Not Modified)を返します。 しかし、何でもかんでもキャッシュするわけではなさそうです。 HTTPサーバ側が etag を返さなかったり、ノーキャッシュのヘッダを返したりすると、 Google Proxy 経由しても何もデータ圧縮を行わずにそのままクライアントに同じ形式でデータが返されました。

他方、HTMLファイルのタイムスタンプだけを変え Etag を更新してみると、 HTMLファイルは取得するのですが、画像ファイルを取得しに来ません。やっぱりコンテンツの中身を見ているのでしょうか?(謎)

以上、詳細仕様は不明ですが、できるだけクライアント側のレスポンスを早く、かつHTTPサーバ側の更新にも合わせるような様々な工夫がされているようです。

5. 実際速くなるの?

じゃ、どの程度早くなるのか? 気になるところです。

以前書いた記事「個人のページでこっそりSPDYを使ってみたら」のHTTPの読み込み測定をするページ(http://html5.ohtsu.org/spdy_test_20130207/without_spdy/)を使ってベンチしてみます。

対象ページは64kbyteの画像が30枚貼ってある単純なもので、Navigation Timing API を使って読み込み時間を取得しています。固定のURLなのでクライアント側のキャッシュに残ってしまいますが、毎回クライアント側のChromeベータをデータ消去して測定しました。

以下、高速なWIFI環境と低速な3G(128kbps)で比べた結果です。Data Compression Proxy 有は、SPDY Proxyを使っているので当然TCPハンドシェイクのオーバヘッドはありません。

WIFI環境でのページ読み込み時間比較


有:無 = 0.5: 1

3G 128kbps環境でのページ読み込み時間比較


有:無 = 0.18 : 1

結構効果が表れてます!

しかし、何回か試すと値にバラつきが出て、毎回必ずしも Data Compression Proxy の方が速いとまだ言い切れません。結果が変わる原因として、Google ProxyサーバからのRTT、コンテンツキャッシュの有無、PageSpeed変換効果やオーバヘッドなど様々な要因が考えられます。

さらに、複数端末の試験を行えていないのですが、キャッシュは複数端末間で共有されるのか否かという部分も気になります。
そうすると皆が使えば全部キャッシュされる。でも知らない人とキャッシュを共有するのはチト気持ち悪い。これを使うときは、機密コンテンツを絶対にHTTPSにしないとダメですね。

まだまだ未知数な部分はいっぱいありますが、しばらくこの状態で使ってみて本当に高速化が体感できるか試してみようと思います。