Instantly share code, notes, and snippets.

@shigeki /commend.md Secret
Last active Aug 29, 2015

Embed
What would you like to do?
「 HTTP/2.0と今後のWebアプリケーションの開発・運用について (#cross2014) 」に対するコメント

このコメントは、

ゆううきブログ : HTTP/2.0と今後のWebアプリケーションの開発・運用について (#cross2014) http://yuuki.hatenablog.com/entry/2014/01/21/114326

の記述に対して私見を書いたものです。こういった先端的な領域では、将来いろんな状況が想定され技術項目の見直しも行われるた、必ずしも一意に正解が決まるわけではありませんが、現状の自分の見込みを元にコメントを記載しています。

注意事項: これはCross2014の登壇者の意見を代表したり、登壇者の意見に対してコメントしたものではありません。あくまでブログの記載内容に対する私個人のコメントですので誤解されないようお願いいたします。

・1リクエストのコストが減る

まず、1リクエストのコストが減る(毎回3-wayハンドシェイクをしない)ため、クライアントサイドでの異常なキャッシュをしなくていいケースがでてくるかもしれない。
  • 毎回3-wayハンドシェイクをしない →HTTP/1.1の場合でもクライアントがkeep-aliveでTCPコネクションを維持できるため、リクエストの度に毎回3-wayハンドシェイクする必要はない。
  • クライアントサイドでの異常なキャッシュ → 具体的に何が異常なのか詳細不明です。リクエストのコストとキャッシュの動作挙動は直接的には関係ないのではないかと思います。(間接的には関係あるだろうけど)

SPDY(HTTP2)のメリットについては、私なら以下の項目を挙げます。

  • 初期接続時HTTP/1.1は最大6回、SPDYは1回のTCPハンドシェイクで済む。ただし preconnect などの機能で初期接続のオーバヘッドを回避できている場合もある。
  • 一つのTCPコネクションをずっと継続して利用するためスロースタートのオーバヘッドが少ない
  • HTTP/1.1の場合はレスポンスの遅延に応じてリクエストがブロック(Head of Line Blocking)されてしまうのに対し、SPDYでは基本的にリクエストがブロックされず、同時リクエスト数の制限がない。ただし通常、初期接続時に最大同時リクエスト数を100程度に制限している場合が多い。
・コンテンツのロード順制御

さらに、ストリームの優先度制御により、例えばHTML、CSS、JavaScriptなどコンテンツの種類に応じてクライアント側でレスポンスの処理順を制御 できる。例えば、CSSレスポンスの処理を優先することができたりするため、CSSが適用されないページが一瞬だけ見えてしまうというような問題を避けられるかもしれない。CSS Spriteみたいな異常なテクニックがいらなくなる。 ストリームの優先度制御について、仕様には以下のように書いてあ る
(中略)
ベストエフォートと書いてあるので、優先度は絶対ではないっぽい。 必ず優先度通りにしてしまうと、クライアントのレスポンスを全部受け取らな いと判断できないからだと思う。

ベストエフォートであるのは、優先度が高いレスポンスデータの取得が完了しない場合(例えばバックエンドのAPサーバからのレスポンス遅延時)に優先度が低いけれどもデータが既にクライアントに対して送信が可能なレスポンスをブロックしないためです。例えば優先度の異なる2つのストリームが両方とも同時に送信可能な状態なら優先順位が高い方を先に送信する、優先度の低い方しか準備できていない場合は優先度が高いストリームを待たずに送信することになるのでベストエフォートという表現になります。

・クライアントライブラリが実装困難

さらに、スマートフォンアプリを含むネイティブアプリでHTTP2.0で通信しようとすると、既存のHTTPクライアントライブラリをそのまま使えなくな る。 もちろん、ライブラリが対応すれば使えるようになると思うけど、HTTP2.0やSPDYはHTTP1.xよりははるかに複雑なプロトコルになっていて、容 易に実装できないので、まともに使えるライブラリは限られてくると思う。

これは個人的な見解ですが、限られるといってもTLS/SSLのライブラリに近い形になると思う。TLS認証・暗号化の処理は複雑なので自前で独自実装する人は少なく openssl 等のライブラリを利用していることがほとんどです。多様なライブラリが提供されればそれなりにメリットもあるでしょうが、以前より 少ないからといって即デメリットにはならないと思います。

・リファラがとれないケース

最後に、場合によってはリファラがとれないというのがある。 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では必須になってる。

現在の挙動を実際に検証していないのですが、http:// => https:// へのリファラは一般に制限されていないと思う。リファラの制限は meta referrer でポリシーを決めることができ、 origin のポリシーを指定している場合の制限を指しているのではないか。(参考資料)

"GoogleのHTTPS版でRefererがoriginだけになりそう (meta referrer="origin")" http://myakura.hatenablog.com/entry/2012/03/20/191406

・TLS処理負荷

まず、HTTPS前提なのでサーバサイドでの暗号化処理の負荷が高まる。proxyの前段のSSLアクセラレータを増やすなど、CPU負荷を分散したりする必要がある

proxyの前段のSSLアクセラレータ という表現は、SSLの処理とproxyの処理するノードが分離されているような印象を受けます。SPDYやHTTP/2の場 合は、TLSのハンドシェイク時のNPN/ALPNの情報に連動してリクエスト・レスポンスの処理も行うため、よほどの事情がない限り分離処理するメリッ トは少ないのではないかと思われます。

・サーバプッシュ

クライアント・リバースプロキシ間だけでなく、リバースプロキシ・Webアプリケーションサーバ間もHTTP/2.0にしないと、サーバプッシュの利用の 仕方が制限されるかもしれない。HTTP/2.0のサーバプッシュについては仕様に以下のような説明がある。
(中略)
上記の前後の仕様を読む限り、プッシュ対象のコンテンツの取得方法は規定されていないようにみえる。

サーバプッシュ機能は、「End-to-End」ではなく「Hop-by-Hop」の機能であるため、クライアントとリバースプロキシ間のみサーバプッシュを利用しても構いません。各ノード間の通信でのサーバプッシュの利用は独立です。ただどういう形が最適なのかはコンテンツの中身やシステム構成に大きく依存すると思います。その意味(最適にできない状況)での「利用の仕方の制限」といったことは生じるかもしれません。

また「プッシュ対象のコンテンツの取得方法」 を「プッシュ対象のコンテンツデータの取得」と同値の意味なら「プッシュ以外のコンテンツデータ の取得」と同じ方法です。おそらく「プッシュ対象のコンテンツファイルが何であるかを決める方法」という意味でしたら「規定されていない」という表現は正しいです。一つの例として、サーバ側があるリクエストがどういうイメージ等のリンク情報が含まれているのかをあらかじめ調べ、その情報を元にコンテンツをプッシュするというやり方です。こういうプッシュするコンテンツを決めるポリシーややり方は仕様では規定されません。

リバースプロキシのみ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)
````

SPDYとHTTP/2ではサーバプッシュのやり方が若干変更されています。
SPDYではサーバがレスポンスを返す前にコンテンツをプッシュします。HTTP/2ではまずリクエストの予約をしてからコンテンツをプッシュするのでサーバがレスポンスを返した後でもコンテンツをプッシュすることができます。


````
逆にWebアプリケーションサーバがHTTP/2.0に対応しなければならないケースは、Server Sent Eventsのように、クライアントがコネクションを切る までサーバがリソースをプッシュし続けなければならない場合だと思う。 リソースをプッシュし続ける場合は、Webアプリケーションサーバからリバースプロキシに対して専用のHTTPヘッダをつけてプッシュして、リバースプロキシがそのプッシュを受けてクライアントにプッシュする必要がある。 ただし、リバースプロキシにWebアプリケーションサーバからのプッシュを受け付けるような機能が実装されるかどうかはわからない。 Webアプリケーションサーバからのプッシュについてはアプリケーションエンジニアの対処も必要になってきそう。

後者については、無理せずにServer Sent Events使ったらよい気がする。サービス内部のトラフィックだと、RTTがそもそも大きくないので、シンプ ルなアーキテクチャであるHTTP/1.1をなるべく使いたい。
````

この部分は正直意味が捉えることができませんでした。Webアプリケーションサーバと Server Sent Event の必要性の関係がわかりません。
Server Sent Event はサーバ側からクライアントへ情報の通知を行うだけで SPDYや HTTP/2でも使うことができます。WebSocketも同様の目的で用い られる場合もありますが、SPDYやHTTP/2での WebSocket の利用はまだ未定なので現状はできないものと考えたほうが良いかと思います。
多分書きたかった事は全然別の意味合いかもしれませんが。


````
・ストリーム優先度調整

特定のクライアントが悪意をもってストリーム優先度を最大にしてしまうと、そのクライアントへのレスポンスを優先してしまうというような問題があるという話もあった。 Googleが重み付き木を使った解決策を提案しているらしい。

悪意がなくてもストリーム優先度が必要なユースケースは存在します。 http://www.slideshare.net/shigeki_ohtsu/http2study3 の p11 の記述を参考にして下さい。

・SSLセッションキャッシュ

ALPNのネゴシエーションのせいで最初のコネクション確立周りのRTTが増えるので、これが気になる場合は接続情報をキャッシュしたりするかもしれ ない。 (01/25追記) リバースプロキシの前段にロードバランサをおいている場合、同じクライアントが同じプロキシにコネクションを張るとは限ら ないので、プロキシ間でmemcachedなどを使って接続情報をキャッシュする必要があるかもしれない。

SSLセッションキャッシュ: Speeding up SSL: enabling session reuse | Vincent Bernat

ALPNの有無でTLSコネクション確立周りのRTTが増える可能性は少ないです。ALPNの情報分サイズが増えるので全くRTTに影響ないかというと可能性は ゼロではありませんが通常無視できる範囲でしょう。

・CDNのHTTP2.0対応

あまりちゃんと見てないけど、Akamaiとかが対応してくれる感じがするので、画像コンテンツをCDNにおいている場合、ほとんど何もしなくても、HTTP/2.0の恩恵が受けられる可能性がある。

SPDY and WebSocket Support at Akamai - The Akamai Blog

ちゃんと仕様を読むと、解決されている問題もあるかもしれない。 今回挙げた以外にもまだまだ影響するところはたくさんあると思う。

CDNやProxyの利用時にHTTP/2でどういう問題があり、どう解決しないといけないかという議論はまだ始まったばかりです。これから徐々に解決策を考えていくことになるかと思います。

その他

QUICは、最初のALPNのネゴシエージョンとか含めて、TCP Fast Open的な感じでRTTを減らす感じらしい。 TCPコネクションを1本化すると、もし高レ イテンシな環境でパケットが落ちまくる場合、TCPのウィンドウサイズが増えないので、スループットが全然あがらないという問題も、何かいい感じ に解決してくれるらしい。(ソースがどこか忘れてしまった) 仕様もないので、具体的にやっていることがよくわからない。

QUICには、FEC(前方誤り訂正)の機能が備わっているので多少のパケットロスはカバーできているのではないかと思います。ただし現状の QUIC通信で実際にどの程度有効に機能できているのかまでは把握していません。現在QUICは活発に開発が進み、とても頻繁に機能更新がされています。Googleの中の人以外なかなか正確な状況を把握するのは困難です。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment