ぼちぼち日記

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

HTTP/2は流行らないけど広く使われるものだと思う。

まずは Disclaimer、
「あくまでも個人の感想であり、HTTP/2の効能を保証するものではありませんw」

1. はじめに、

先日、HTTP/2, HPACKのRFC(7540,7541)が無事発行されました。2年余りHTTP/2の標準化活動に参加してきたのですが、もうすっかり昔の事のような感じがします。

今日、Scutumの開発をされている金床さんの「HTTP/2のRFCを読んだ感想」のエントリーが公開され、読ませて頂きました。今回初めてHTTP/2の仕様書を読まれた感想ということで、長くかかわってきた立場から見ると非常に新鮮な内容でした。

実は「HTTP/2が流行らない」という指摘は、1年半ほど前に私も同じことを書いていました。
HTTP/2.0がもたらす Webサービスの進化(後半)

また、偶然なのかわかりませんが、同じ Proxy製品 vanish varnish *1 の開発者(およびFreeBSDの主要開発者)の PHK さんも同様な指摘をしています。「HTTP/2.0 ― The IETF is Phoning It In Bad protocol, bad politics」 もっとも、彼の記事では技術的な点だけでなく仕様策定のガバナンスへの批判も含まれていますが。

流行る、流行らないの議論で言うと、現状の利用用途に限れば中小規模のサービスや個人の用途でHTTP/2のサーバが広く使われるようにならないでしょう。ただ現状 Google/Twitter/Facebook/Yahoo.com 等が既に HTTP/2やSPDY をサポートしており、Chrome/Firefox/Safari/IEを通じて非常に多くのユーザが意識せず利用しています。それは現状のインターネットトラフィックのかなりの割合です。

なので私の予想は、
「HTTP/2は流行らないけど広く使われるもの」
です。

でも個人的には、将来HTTP/2固有の機能を使った中小サービスでも使いたくなるようなHTTP/2のユースケースが出てきて流行って欲しいなと願っています。

2. 各記述に対するコメント

予備知識なしで全く初めてHTTP/2の仕様書を読まれた金床さんの記事中の感想は、おそらく他の方が読まれても同様なことを感じるはずです。個々の感想に反論するつもりは全くありませんが、仕様策定に携わった立場でフォローをすれば、両者の記事を読んだ方々に対してHTTP/2に対する理解が深まることになればと期待してコメントを書いてみます。

できるだけ前後の文脈を壊さない程度で1・2センテンスを引用していますが、不適切な部分があればご連絡下さい。

HTTP/2が出た

サーバ側を作っているのもGoogle、ブラウザ(Chrome)を作っているのもGoogleで、そんなに高速化したいならUDPでも使えばよいのでは...などと、とりあえず様子を見ていました。

他の方も指摘しておられますが、GoogleQUIC, a multiplexed stream transport over UDPを開発し、現在全サービスで試験利用しています。TCP+TLS相当の機能+αを備えたQUICは、 HTTP/2 とは比べ物にならないぐらい複雑です。導入するには、HTTP/2より遥かに高い技術ハードルを超えないといけないでしょう。

RFCを読んだ最初の印象

HTTP/2はHTTP/1.0やHTTP/1.1を入れ替えるものだろうと思っていたのですが、まったくそうではなく、従来のHTTP/1.1はそのままに、その外側にさらにかぶせて使うものだったのです。

HTTP/2の仕様策定を開始するにあたりchartersが定義されました。その中に「HTTP/1.1のセマンティクスを保持する」の一項目が含まれています。できる限り既存のHTTP/1.1との親和性を保つのがHTTP/2の大きな方向性です。

PHKは、SPDYがHTTP/2のベース仕様として採択された時 「Why HTTP/2.0 does not seem interesting」 という記事で「現状のHTTP/1.1には改善すべき点がいくつかあり、HTTP/2はスクラッチから始めるべきだ」と主張しました。結局彼の主張は受け入れられず、今のインターネットサービス大手が直面している課題を解決するべく現実路線を進む判断がされました。

そして、中間会議や相互接続試験を頻繁に行い、異例なスピードで仕様策定が進められました。その結果、仕様候補決定からわずか2年あまりで仕様化完了し、それと共に今あるようブラウザのHTTP/2実装の大規模デプロイまでたどり着いたわけです(当初は昨年4月完了予定でしたが)。

新しい標準を迅速に出し、短期間で大規模にデプロイする。この目標は仕様策定に中心的にかかわったメンバー全てに共有できていた意識です。素早い進化が求められる現在のインターネット技術にあった方針だと思います。

  • 並列性のサポート

しかし例えば「HTTP/1.1より3倍速くなった!」ということは難しいでしょうから、普通の開発者やユーザからしたら「ちょっと速くなったね」程度の話で、果たして新しいプロトコルを定義するほどのメリットがあるのか疑問に思います。

HTTP/2の並列性のサポートの大きな目的は、HTTP HoL(Head of Line) Blocking の回避です。現状のHTTP/1.1の利用では、一つのクライアントから同時に4〜6の接続に制限され、多くのリソースを同時にリクエストするようなサービスでは、レスポンスの遅延に伴うリクエストのブロックが全体の表示速度に大きな影響を与えます。

HTTP/2の導入を検討するような大規模サービスでは、この HTTP HoL Blocking が発生している状況か?、 HTTP HoL Blocking の解消によってページの表示速度が改善するか? といったことを見極めるのが大事です。

  • ヘッダの圧縮

ヘッダの圧縮も並列性のサポートと同様で、もちろん良いだろうとは思いますが、新規にプロトコルを定義するほどのメリットがあるとは思えません。大きなHTMLやJavaScript等を、従来の枠組みの中で可能であるgzip圧縮すればよいだけだろうという気がします。

引用ではHTMLやJavaScriptgzip圧縮を代替え案として挙げていますが、HTTPヘッダのデータをgzip圧縮をすることも指していると想定してコメントします。

HTTP/2の前身のSPDYでは、HTTPヘッダのgzip圧縮が行われていました。しかしCRIMEという攻撃手法が公開され、TLS で暗号化された通信上でも圧縮データのサイズを判別することでヘッダ情報が漏えいするといった脆弱性が発見されました。そのため現在のSPDYではクライアントからのリクエストヘッダの圧縮は無効化されています。

しかしHTTPは、クッキーやユーザーエージェント等の冗長で繰り返し送受信されるヘッダ情報が多く、ヘッダデータの圧縮による通信量削減は効果が大きいです。

HTTP/2では、HPACK というHTTPヘッダに特化した圧縮技術が開発されました。全く新しい仕組みであるため途中仕様が右往左往しましたが、最終的に平均で3割程度の圧縮率が達成できています。

ただ肝心のCRIMEの脆弱性対策ですが、gzip よりも困難になりましたが、完全に対策できているものにはなりませんでした。結局フレームにパディングを入れてサイズをごまかしたり、機密度の高いヘッダ情報は圧縮用にインデックスしないなど HTTP/2 時代でも CRIME攻撃を意識してHPACKを使わないといけない状況です。この辺、まだまだ技術的な改良の余地が今後あるでしょう。

  • ステートフルすぎる

HTTP/2では複数のストリームやプライオリティ、依存ツリーなど、とにかく大量の状態を管理する必要があります。これは「リクエストが来たらレスポンスを返す」だけだったHTTP/1.1と比べると非常に大きな違いで、実装は今までのHTTP/1.1と比べ、とてつもなく複雑化すると思われます。

これは同意です。特にプライオリティ実装は非常に大変です。幸いなのは機能的にオプション扱いでまだこれから実験段階の機能であるということです。ただ仕様書を注意深く読み込まないとこの辺の判断はできないと思いますね。

  • 他のレイヤーとクロスオーバーしすぎている

HTTPのRFCであるのにTLSに言及している箇所があったり、データの転送について、まるでTCPのようにフロー制御の機能があったりと、きれいに「そのレイヤー」に収まっていない印象を受けました。

ここはTLS・フロー制御の2つ項目が挙げられていますが、別々の理由があります。

  • TLSの(厳しい)要件の導入

ここは大きな議論がありました。HTTP/2に必須なALPNによるネゴシエーションだけでなく、暗号強度や種類など通常のTLS利用より厳しいTLS要件が記載されているからです。

これは当初、既存のTLS1.2までは後方互換重視でつぎはぎ的な技術対応がされており、TLS上での利用が大部分を占めるHTTP/2では、できるだけ安全な条件の上で通信を行うべきであるという方針からです。他方、下のレイヤーのTLSはどんなものであろうと受け入れるべきであるとの意見もあり、ラストコール直前で大きな議論に発展しました。

結果的に今の仕様のように200以上の暗号のブラックリストを加えることになってしまいました。本来 TLS1.3 の仕様化が完了していれば、単にHTTP/2はTLS1.3上のみサポートということになっていたでしょう。

  • フロー制御の導入

フロー制御は当初のSPDY/2ではなかった機能です。1本のTCP内で複数のストリームが帯域の取り合いし、競合してしまうのでSPDY/3から導入された機能です。そして全体の帯域を有効活用できるようコネクションレベルのフロー制御がSPDY/3.1から導入されました。詳しくは、 twitterが spdy/3.1 の試験を始めてます を読んで下さい。

  • 複雑すぎる

全体的に、それほど大きなメリットがなさそうなのにやたら複雑になってしまっている印象を受けます。

  • 単に追加するだけで何も減らせていない

HTTP/1.1から無駄な部分(個人的には思いつきませんが)を極力減らし、シンプルにした上で出てくるのであればまだしも、単に追加だけしてしまっているので、開発者の負担を増やす方向にのみ向かってしまっています。

複雑さと機能追加の議論は本当に揺れ動きました。

これでもラストコール直前に様々な機能が拡張機能に追い出され、だいぶスリム化が図られたものです。
ただ複雑さは高度な運用ノウハウが必要になるものと思われます。ここ数年でHTTP/2を本当に使いこなせるようになるところはそれほど多くないでしょう。

  • これは流行らないかも

HTTP/1.1にとても大きな不満がなければ、HTTP/2を積極的に導入しようとするモチベーションは湧きません。

これは完全に同意します。HTTP/1.1をdeprecateしてHTTP/2への移行するということはないので、現状のHTTP/1.1の利用で大きな不満がなければ、継続的に使い続けるのがよろしいかと思います。

  • WAF開発者としての視点から

具体的には、PINGやPUSH_PROMISEなどによってWAF側から積極的にクライアントに対して働きかけ、反応を見ることで実装のフィンガープリンティングがやりやすくなりそうです。

この視点は新鮮でした。例えばFirefoxは接続を切られないよう1分毎にPINGを送ってきます。他にも、仕様では Connection Error/Stream Error の2種類のエラーとその発生条件が定義されていますが、各実装によって微妙に違うような感じがします。もしかするとエラー時の挙動の違いでクライアントやサーバの特定ができる可能性があるかもしれません。

と、以上ずらずら書いていたら思わず長文になってしまいました。少しでも皆さんの HTTP/2 に対する理解が深まれば幸いです。

*1:typo修正しました。khtokage さん、ご指摘ありがとうございました。