追記 @jovi0608 さんに非常に丁寧にコメントをいただきました。
https://gist.github.com/shigeki/ba7941d114344ddd4b01
本文 CROSS 2014の次世代Webセッションに参加した。 いろいろ刺激を受けたので、特に、Webアプリケーションを開発・運用する上で、今後どう影響してくるだろうみたいな視点で整理したことを書いてみた。
次世代Webセッションは去年もUSTで見てて、めっちゃ面白かったので、今年は生で聞きに来た。 去年のセッションの議論は、 naoyaさんの記事が雰囲気がわかりやすかった。
去年、SPDYの内容とか追ってて、HTTP/1.1と何が違うのかみたいなことを調べて書いたりしてた。
次世代Webセッションの特にプロトコル編は前提知識ないと全然追いつけないという事前情報があったので、東京行く前に復習してた。 去年は、わかりやすく解説してくれる日本語記事少なかったように思うけど、この一年でいい情報増えててありがたかった。 いろいろ読んだけど、SPDYについては特に以下の記事が要点がまとまっててすばらしい感じだった。
ネットワークパフォーマンスやスケーラビリティについては以下の記事が参考になる。
今年の様子は、UstreamとTogetterがある。
- Ustream Ustream.tv: ユーザー nifty_engineer: cross-a, cross-a. Web (次世代Webセッションが30分ぐらいから始まってる)
- Togetter 次世代 Web セッション #cross2014 - Togetterまとめ
去年はbreak the web
という言葉がでていたけど、QUICの登場により今年は、TCP/IPを壊す
という話まででてしまった。
TCP/IPの代わりみたいな話は過去に無限にあると思うけど、Webの話からの流れで、TCP/IPの代わりの話ってまずないと思う。
QUIC自体はTCP/IPを壊すというものではないけど、TCPの代わりに独自のフロー制御/輻輳制御をやるということは、Webが確実にそのレイヤに侵食しはじめたということなのかもしれない。(TCPの公平性みたいな話どう担保するのか気になる)
Webアプリケーションの開発・運用にどこまで影響するのか
HTTP/2.0を導入するメリットとか導入の際に注意するべき立場によって違うと思う。 当日の話を聞いたり、自分で調べたりして、特に自分のレイヤーに関係してきそうなことを並べてみた。 HTTP/2.0はまだ仕様が策定中なので、今後状況は変わってくるかもしれない。(セッション中に、GoogleがWebSocket over SPDYをやってみてHTTP/2.0に還元するみたいな話もあった)
ちなみに、HTTP/2.0の仕様はGitHubで管理されてる。
2013/01/20現在、draft-ietf-httpbis-http2-09 - Hypertext Transfer Protocol version 2.0が最新の仕様で、日本語訳もある Hypertext Transfer Protocol version 2.0 (draft-ietf-httpbis-http2-09) 日本語訳。
アプリケーション実装視点
- 1リクエストのコストが減る
- スマートフォン環境でのレスポンスタイム削減
- コンテンツのロード順制御
- クライアントライブラリが実装困難
- リファラがとれないケース
- 1リクエストのコストが減る
まず、1リクエストのコストが減る(毎回3-wayハンドシェイクをしない)ため、クライアントサイドでの異常なキャッシュをしなくていいケースがでてくるかもしれない。
- スマートフォン環境でのレスポンスタイム削減
次に、3-wayハンドシェイクの回数が少ないため、無線環境のような高レイテンシ環境でパケットロスによる再送が減り、結果レスポンスタイムが小さくなる。 スマートフォンアプリ/スマートフォン対応サイトにはかなり有利だと思う。 ただし、後ろでも書いてるけど、パケットロスが多すぎると、スループットがでない。
- コンテンツのロード順制御
さらに、ストリームの優先度制御により、例えばHTML、CSS、JavaScriptなどコンテンツの種類に応じてクライアント側でレスポンスの処理順を制御できる。例えば、CSSレスポンスの処理を優先することができたりするため、CSSが適用されないページが一瞬だけ見えてしまうというような問題を避けられるかもしれない。CSS Spriteみたいな異常なテクニックがいらなくなる。 ストリームの優先度制御について、仕様には以下のように書いてある。
5.3. ストリームの優先度
新しいストリームを確立するエンドポイントは、ストリームに対して優先度を割り当てることができます。優先度は符合なし31ビット整数で表現されます。0は最も高い優先度を表し、231-1は最も低い優先度を表します。
この値の目的は、あるストリームのフレームが、他の並行するアクティブストリームよりも高い優先度で処理されることを、ストリームを開始したエンドポイントが要求できるようにすることです。これにより、あるエンドポイントが複数のストリームからインターリーブされたフレームを受信した場合、そのエンドポイントは、優先順位の低いストリームのフレームを処理するより前に、優先度の高いストリームのフレームの処理をベストエフォートで試みるべきです。 http://summerwind.jp/docs/draft-ietf-httpbis-http2-04/#section5-3
ベストエフォートと書いてあるので、優先度は絶対ではないっぽい。 必ず優先度通りにしてしまうと、クライアントのレスポンスを全部受け取らないと判断できないからだと思う。
- クライアントライブラリが実装困難
さらに、スマートフォンアプリを含むネイティブアプリでHTTP2.0で通信しようとすると、既存のHTTPクライアントライブラリをそのまま使えなくなる。 もちろん、ライブラリが対応すれば使えるようになると思うけど、HTTP2.0やSPDYはHTTP1.xよりははるかに複雑なプロトコルになっていて、容易に実装できないので、まともに使えるライブラリは限られてくると思う。
- リファラがとれないケース
最後に、場合によってはリファラがとれないというのがある。 HTTP2.0はTLSの上で通信する(HTTPSで通信する)ため、https://のページからhttp://のリンクにとぶと、リファラが送出されなくなる HTTP/1.1: Security Considerations。 (仕様にはSHOULD NOTと書いてあるので、絶対ではない) 会員制のサービスのように、自前のサービスで完結しているところは気にしなくていいけど、ブログサービスとかニュースサイトやっているところが、HTTPSになってしまうと、自分のサイト(https://)から広告サイト(http://)への流入量とかわからなくなるかもしれない。 なぜリファラを送出しないかというと、https:// => http:// は社内Wikiとかに外部のhttp://リンクを張ってそのリンクを踏んでしまうと、平文のリファラに社内WikiのURLが含まれてしまうなどの不都合が起きるからだと思う。 http:// => https:// についてはよくわからない。 ちなみに、TLS必須にするかどうかはまだ議論中らしい。SPDYでは必須になってる。
オペレーション視点
- TLS処理負荷
- サーバプッシュ
- C10K回避
- ストリーム優先度調整
ALPNのネゴシエーションキャッシュSSLセッションキャッシュ- CDNのHTTP2.0対応
- TLS処理負荷
まず、HTTPS前提なのでサーバサイドでの暗号化処理の負荷が高まる。proxyの前段のSSLアクセラレータを増やすなど、CPU負荷を分散したりする必要がある GPUを用いたSSLリバースプロキシの実装について - ゆううきブログ。
- サーバプッシュ
クライアント・リバースプロキシ間だけでなく、リバースプロキシ・Webアプリケーションサーバ間もHTTP/2.0にしないと、サーバプッシュの利用の仕方が制限されるかもしれない。HTTP/2.0のサーバプッシュについては仕様に以下のような説明がある。
例えば、サーバーが複数の画像ファイルへのリンクが埋め込まれた文書のリクエストを受信し、サーバーがそれらの画像をクライアントにプッシュすることを選択したとします。このような場合、その画像リンクを含む DATA フレームよりも前に PUSH_PROMISE を送信することで、クライアントがそのリソースを見つける前に予約を確認できることを保証します。同様に、ヘッダーブロックが参照するリソース (例えば、Link ヘッダーフィールドなど) をプッシュする場合は、ヘッダーブロックを送信する前に PUSH_PROMISE を送信することで、クライアントがそのリソースにリクエストしないことを保証します。 http://summerwind.jp/docs/draft-ietf-httpbis-http2-09/#section8-2-1
上記の前後の仕様を読む限り、プッシュ対象のコンテンツの取得方法は規定されていないようにみえる。
リバースプロキシのみHTTP/2.0対応すればよいケースは以下の様な感じだと思う。 ある文章に含まれた画像リンクをリバースプロキシへのレスポンスに含まれるX-Associated-ContentヘッダにWebアプリケーションサーバが入れて、リバースプロキシは文章をまずクライアントにレスポンスしてからリクエストを待たずにX-Associated-Contentヘッダに含まれるリンクの画像を取得するとかになるかもしれない (X-Associated-Contentのやり方はmod_spdyのやつ https://code.google.com/p/mod-spdy/wiki/OptimizingForSpdy#Using_SPDY_server_push)
逆にWebアプリケーションサーバがHTTP/2.0に対応しなければならないケースは、Server Sent Eventsのように、クライアントがコネクションを切るまでサーバがリソースをプッシュし続けなければならない場合だと思う。 リソースをプッシュし続ける場合は、Webアプリケーションサーバからリバースプロキシに対して専用のHTTPヘッダをつけてプッシュして、リバースプロキシがそのプッシュを受けてクライアントにプッシュする必要がある。 ただし、リバースプロキシにWebアプリケーションサーバからのプッシュを受け付けるような機能が実装されるかどうかはわからない。 Webアプリケーションサーバからのプッシュについてはアプリケーションエンジニアの対処も必要になってきそう。
後者については、無理せずにServer Sent Events使ったらよい気がする。サービス内部のトラフィックだと、RTTがそもそも大きくないので、シンプルなアーキテクチャであるHTTP/1.1をなるべく使いたい。
- C10K回避
あとは、多重化やサーバプッシュのおかげでとにかくコネクション数が抑えられるので、単純にC10K的な問題が抑えられそう。 ファイアフォールのトラッキングテーブル(ip_conttrackとか)溢れなんかも抑えられそう。
- ストリーム優先度調整
特定のクライアントが悪意をもってストリーム優先度を最大にしてしまうと、そのクライアントへのレスポンスを優先してしまうというような問題があるという話もあった。 Googleが重み付き木を使った解決策を提案しているらしい。
- SSLセッションキャッシュ
ALPNのネゴシエーションのせいで最初のコネクション確立周りのRTTが増えるので、これが気になる場合は接続情報をキャッシュしたりするかもしれない。 (01/25追記)
リバースプロキシの前段にロードバランサをおいている場合、同じクライアントが同じプロキシにコネクションを張るとは限らないので、プロキシ間でmemcachedなどを使って接続情報をキャッシュする必要があるかもしれない。
SSLセッションキャッシュ: Speeding up SSL: enabling session reuse | Vincent Bernat
- CDNのHTTP2.0対応
あまりちゃんと見てないけど、Akamaiとかが対応してくれる感じがするので、画像コンテンツをCDNにおいている場合、ほとんど何もしなくても、HTTP/2.0の恩恵が受けられる可能性がある。
SPDY and WebSocket Support at Akamai - The Akamai Blog
ちゃんと仕様を読むと、解決されている問題もあるかもしれない。 今回挙げた以外にもまだまだ影響するところはたくさんあると思う。
その他
QUICは、最初のALPNのネゴシエージョンとか含めて、TCP Fast Open的な感じでRTTを減らす感じらしい。 TCPコネクションを1本化すると、もし高レイテンシな環境でパケットが落ちまくる場合、TCPのウィンドウサイズが増えないので、スループットが全然あがらないという問題も、何かいい感じに解決してくれるらしい。(ソースがどこか忘れてしまった) 仕様もないので、具体的にやっていることがよくわからない。
WebRTCの話もあった。
自分の環境だと、WebRTCみたいなP2Pの仕組みが必要なほどレイテンシ要求がシビアなアプリケーションを触らないと思う。
LINEはサーバ介して普通に低レイテンシで捌けてるし、今のところゲームくらいしか用途がなさそうなイメージがある。
オンラインゲームを支える技術
とか読むとレイテンシの厳しさがよくわかる。
オンラインゲームを支える技術 ??壮大なプレイ空間の舞台裏 (WEB+DB PRESS plus)
- 作者: 中嶋謙互
- 出版社/メーカー: 技術評論社
- 発売日: 2011/03/24
- メディア: 単行本(ソフトカバー)
- 購入: 33人 クリック: 1,696回
- この商品を含むブログ (53件) を見る
まとめ
ゲームとかリアルタイムWeb的なアプリケーションがHTTP/2.0の恩恵を受けられるのは間違いないけど、スマートフォン時代ということを考えると、それ以外のアプリケーションでもパフォーマンス的なメリットは大きそうに思う。 一方で、ブログのようなオープンインターネット的なサービスだと、暗号化前提な世界観によりリファラがとれないなどの問題がでてきて、サービス展開に影響がでてきそうな危惧がある。
参考
- 実装についての貴重なエントリ。人間とウェブの未来 - mod_spdyから学ぶSPDYとストリーム並列処理の実装
- ALPNについて。HTTP/2.0のALPN利用に伴うSSL負荷分散装置の不具合にご注意下さい - ぼちぼち日記
- 読んでないけど書籍なら
High Performance Browser Networking
がいいらしい。
- 作者: Ilya Grigorik
- 出版社/メーカー: O'Reilly Media
- 発売日: 2013/09/11
- メディア: Kindle版
- この商品を含むブログを見る