Block Rockin’ Codes

back with another one of those block rockin' codes

これからの Web の話をしよう。 (次世代 Web セッション @ CROSS2014)

Update

2014-01-19 振り返り

CROSS2014 が無事終了しました。

以下ログです。ビデオは前のセッションとかぶっているので 35 分くらいからが本セッションです。


去年に引き続き、今年もなかなか密度の高い内容になったんじゃないかと思います。

プロトコル編では、普段なかなか表に出てこない方を中心にお呼びして、2013 年から今日までの流れを踏まえつつ、今起こっているプロトコル的な変化を浮き彫りにし、今後の HTTP2.0 の展望や QUIC の持つ意義などを話し合いました。
象徴的なのは「TCP/IP の破壊」などという想定外に振り切った本音に見て取れるかと思います。こうした発言が出たあたり、非常にやった甲斐を感じました。


アーキテクチャ編は、去年より幅広いポジションの方々に出て頂き、それぞれの視点から現実的な話をして頂きました。去年の CROSS で「リアルタイム」として語っていた内容が、「ゲーム」というより具体的なものに繋がり、新しい技術の適応先の一例として興味深い話も出ました。確かに今回は出て頂いた方の携わる分野的な偏りもあったと思いますが、それでも現在の Web について語る上で、ゲームを「完全には無視できない」というのが自分としては盲点だったところかと思います。


全体を通しては、「TLS 前提の Web」という風潮の是非に対する、プロトコル編 / アーキテクチャ編双方のスタンスに割と明確な差異が見いだせました。プロトコルを考えるロール、それを用いてサービスを運用するロール、双方の意見が聞けたのがこのセッション構成をとった 1 つのメリットとして見いだせたのかなと思っています。


反省点は色々ありますが、少なくとも [twitter:muddydixon] さんに「もうやるな」と言われない限りは続けていきたいなと思っています。
(あと、 1 年に 1 回だと少し間が長いし、もっと色々な方とも議論もしてみたいので、 CROSS 以外にも場を作ったり、場が無ければ Podcast にしてみても面白いかなぁ、などと思っています。)


あまり俺が色々書くより、セッションの最後でも話した、参加者による「自分の考える次世代 Web」ブログにそこは譲って(出てくるといいなぁw)、自分のまとめとしてはここまでで。

最後に、出て頂いた登壇者の皆さん。参加して下さったみなさん。そして CROSS スタッフのみなさん。本当にありがとうございました & お疲れ様でした!

Jxck



Intro

2014/1/17(Fri) に開催される CROSS2014 にて、
CROSS2013 に引き続き「次世代 Web セッション」というセッションを担当させていただくことになりました。

今日はこのセッションの意図と概要について書こうと思います。
セッションで扱わない内容などについても言及するので、参加される方はこのエントリを README(趣意書) だと思って参加前に目を通して頂ければと思います。


去年のログ: これからの Web の話をしよう。 (次世代 Web セッション @ CROSS2013)

テーマ

このセッションのメインテーマは去年と同じです。

「次世代 Web セッション」ではいま起こっている Web の変化について、

  • 「何が起こっているのか」
  • 「どこに向かっているのか」

を議論することを目的としています。


また、その議論の主軸を絞るために 2h の枠を

の 2 つのセッションに分けて議論します。

登壇者

今年も豪華な登壇者の方々に集まって頂くことができました。
(公式サイト用プロフィールを引用)

プロトコル編」

@さん
Aria2/Spdylay/nghttp2/Wslay の作者 https://github.com/tatsuhiro-t
@ さん
Chromium Project にて、主に WebSocket, XHR の実装及び関連仕様の標準化を担当。それ以前は、現職にて Load balancer の開発、大学にて FPGA を用いた TCP/IPv6/10GbE の高速化研究など。
@ さん
2009年頃から主にIETFを中心とした標準化活動に参加。現在、通信プロトコル、認証・認可等のセキュリティ領域、プログラミング言語処理系等を主な活動対象としている。


アーキテクチャ編」

@ さん
2011年よりカヤックに入社。自社サービス、ソーシャルゲームのサーバインフラ、運用、監視を担当。
@ さん
2006年はてな入社、2010年より2代目CTO。技術的なことであれば、なんでも好物。はてなのサービスと技術の進化を加速させていきます。著書に「サーバ・インフラを支える技術」「大規模サービス技術入門」など
@ さん
ネットウォッチが高じてプログラマに。とにかくJavaScriptを高速化したい。ネイティブに負けたくない。CoffeeScript等のAltjsが好きで、最近だとLLVMEmscriptenに興味がある。

モチベーション

Web は絶えず変化しています。前回の CROSS2013 からも 1 年経って変わったところがいくつもあります。
この変化をキチンと把握し続けるのはなかなか難しいことです。

例えば「SPDY とは?」といった部分的話は割りとしやすいので、初心者向けの話は多くのイベントでされています。
(自分もよくお話させて頂いています。)

一方で、そうした初心者向けの話は、もう聞き飽きている人も多くいます。
しかし、初心者向けセッションの「その先」を扱うのは実は難しいのが現実です。


次世代 Web セッションは「その先」に挑戦したいと思っています。


「どこに向かっているのか」に答えを持っている人はいません。しかし、僕ら技術者はそこにコミットすることはできると思います。

「どこに向かっているのか」を考えるには、まず今「なにが起こっているか」をきちんと把握する事も必要です。


そこで自分は

  • 「何が起こっているのか」
  • 「どこに向かっているのか」

について、きちんと議論する場を作りたいと思い、その議論ができるであろう方々に声をかけさせて頂きました。

お断り

このセッションは、答えを出すセッションではありません。
答えが出せる、出ているような話は、わざわざここで議論する気はありません。


自分たちが「次世代の Web」を考える上で必要な知見を、常にそれを考えて戦っている方々との議論の中から見出そうというのがこのセッションの目的です。


参加するだけで答えが教えてもらえるという期待を持つ方は、このセッションには参加しないことをおすすめします。

扱わない内容

1 時間は、ちょっと真面目に議論すればあっという間に過ぎてしまう時間です。
その限られた時間の中で本来のテーマに集中するために、切り捨てる内容について書きます。

これは、自分が今回「あまり積極的に扱う必要がない」だろうと考えているものです。 といってもさじ加減なので、実際は登壇者の方々に委ねます。
しかし、参加者の方には「前提」として考えていただきたいと思っています。

初心者向け内容

例えば「SPDY とは何か?」「REST とは何か?」「IETF とは何か?」etc といった話には時間を割きません。
ある程度の知識は前提として、それを踏まえて先について話すことを重視します。
知識を得て Catch Up するためではなく、議論を通して Move Up するセッションにしたいという思いがあります。

過去の事

今回、テーマにはあえて「過去」を入れていません。 懐古するためのセッションとは考えていません。

  • 「何が起こっているのか」(現在)
  • 「どこに向かっているのか」(未来)

もちろん、古きを知ることは重要です。
過去の事例が引き合いに出ることもあると思いますが、過去を改めてから未来を語るには時間がたりません。
過去は基本的には共有された前提として考えて、「その先」にフォーカスして議論したいと考えています。

登壇者紹介

こうしたセッションで、自己紹介で大きく時間を浪費するセッションをよく見ます。
今回の登壇者のみなさんは著名な方が多く、このセッションを聞きに来る方は知っている人が多いと思います。
彼らの自己紹介に時間を割く気はありません、みなさん自己紹介を聞きに来るわけでもないでしょう。
なので、冒頭に自分がみなさんの名前を紹介する程度とさせて頂きます。


各登壇者の紹介は、このエントリや公式サイトのセッション概要から見ることもできますので。予め見ておいて頂けると良いと思います。

進め方

流れを決めすぎると予定調和になってしまうので、打ち合わせの段階でおおまかな方向性とキーワードのみを決めておき、
当日はそれについて基本的にはフリースタイルで議論を進めていきたいと思っています。


あまりズレて行くなら、途中で切るなどはしすまが、その場で起こる議論をなによりも大事にしたいです。

雰囲気については、去年の映像をご参照下さい。

まとめ

最後にもう一度。
このセッションは、 Web について

  • 「何が起こっているのか」
  • 「どこに向かっているのか」

に 1 時間フォーカスし続け、「その話はもう知ってるよ」とか、「何度も聞いたよ」みたいな話を無くして、少しでも議論の密度を高めたいです。
そのために参加者には「前提」を求める部分が多くなる点はありますが、限りある時間を有効に使うためにご理解ください。
これだけの方が揃ったセッションなので、変わりゆく Web の今後を考える上で、少しでも熱く有益な議論ができる場を作れればと考えています。


今年も去年同様、「最後は自分の頭で考えろ」(by @) で行きたいと思います。
このセッションで得たものをベースに、あなたが考える「次世代 Web」についてのエントリが読めることを、楽しみにしています。

Jxck

#BPStudy72 で SPDY / HTTP2.0 / QUIC のお話をさせて頂きました。

intro

ちょっと遅くなってしまいましたが、 BPStudy#72 にて、 SPDY / HTTP2.0 / QUIC についてのお話をさせて頂きました。

BPStudy#72 - connpass

資料

発表資料です。


資料は以下です。今回は、とりあえず上記 3 つを全部突っ込もうということで盛りだくさんな感じになってしまいましたが、現時点での話は割りと網羅できた気がします。


盛り込んだバージョンは、 2013/8/28 時点のものなので、バージョンでは以下のような感じです。

  • HTTP/2.0 draft-06
  • HPAC draft-03
  • SPDY/3
  • QUIC (現状)


当日の朝に HPAC の仕様が新しくなったり、 devops-ML ができたりと動きがあり、行ってから直したりしました。
週末に作った資料が水曜には古くなっているという程度の動きの速さなので、今回の資料も賞味期限は早めだと思いますが、ご注意下さい。


BPStudy

BPStudy は今回でちょうど 6 年目だそうです。もうそんなにやっているんですね。
いわゆる勉強会ブームの初期か、その前くらいから開催されていて、自分も気になるトピックを見つけては、ちょくちょく参加して勉強させていただいていました。それが今回初めて登壇者として声をかけていただいたので、とても光栄です。


技術系の会社が、自分たちの技術をキチンとアップデートするために、こうした取り組みをするだけでも凄いのに、
それを定期的に続けてここまで来たというのは素晴らしいことだと思います。
それも、代表の佐藤さんが技術について真剣に向き合ってきたからなのでしょう。


今後も興味のあるテーマは是非参加させて頂きたいと思います。
これからも有益な勉強会を期待しております。
ありがとうございました。

なぜ QUIC や SPDY が生まれたのか ?

Intro

Google が SPDY の開発を始めたのは 2009 年で、 2012 年に HTTP2.0 のドラフトとして採用されたあたりからちょっと話題になりました。
翌 2 月には新たなプロトコル QUIC の存在が Chromium のソースからリークしたのですが、しばらくは音沙汰なく。
6 月に入ってやっと Google から公式アナウンスとドキュメント類が出ました。


去年から今年にかけて立て続けに出てくる新しいプロトコルの話。
なぜ今 Web のプロトコルが見直されるのか?
何が問題で、なぜ Google はそれらを作り変えるのか?


SPDY や QUIC は Google の独自プロトコルだけど、それは本当にただの独自プロトコルで終わらせていいのか?
20% ルールで作ってみた Play プロジェクトでしかないのか?


こうした新しい動きには、かならず「それまで」と「今」を踏まえた議論が起こります。
つまりこれらを追うと、「今何が起こっているのか?」を知ることができて非常に得るものがあります。


プロトコルの解説は何度か書いたけど、そういう話をもう少し書いてもいいかと思い
自分がわかる範囲でちょっとつらつらと書いてみようかと思います。

Web を速くするということ

単純にWeb を高速化するといっても様々なレイヤがあります。
たとえば、ぱっと浮かぶ範囲でも以下のようなものがあります。

  • A, Web アプリ/システム/サービスの高速化
  • B, ブラウザ、サーバプロダクト、カーネルのネットワーク周りなどの高速化
  • C, ネットワーク機器などの高速化
  • D, ネットワーク帯域などのインフラの強化


A は、 Web アプリがあってそれが遅いから速くしようとした場合です。
ISUCON で行われているようなチューニングなんかが浮かぶでしょう、これは一般の開発者にとって一番手を出しやすいレイヤになります。自分のアプリなので、アップデートもしやすいです。


B は、 Chrome が速くなる Nginx が速くなるとかといったレイヤです。
OSS であれば、パッチを投げることで貢献はできますが、自分のプロダクトに手を加えるのと比べれば多少敷居は上がるかもしれません。アップデートは定期的なものになり、多少時間が必要なります。


C は、 アプリの開発者からは通常意識されないレイヤで、ネットワーク上の機器とかそういうレイヤになりますかね。 PC 自体の NIC とかも入るかもです。本格的にハードがからんでくるので、アップデートはより時間がかかるし、なかなか手を入れることも難しい部分になってきます。


D は、通常一般の開発者では手が出ないレイヤです。ネットワーク事業者などがインフラに投資をすることで、改善していきます。わかりやすいのは帯域の改善などです。サイクルは、、ものによるとしか言えないかもです。


さて、これらの改善は、独立して実施できます。つまり、それぞれが別々に努力をして改善でき、それらが組み合わさって全体を「速く」することができます。


なぜ、独立で実施できるか。これはネットワークの世界にレイヤの考え方があり、各レイヤに「約束事」としての標準プロトコル/フォーマットが存在するからです。担当するレイヤの中で、プロトコル/フォーマットに従って実装をしていれば、「相互接続性」が保たれ、プロダクトなどをアップデートしても「Web が壊れる」ことを防ぐことができます。これが、プロトコル/フォーマットを「標準仕様」として定義するメリットです。


独立で実施できるということは、大げさにとらえると、あるレイヤが改善すればボトルネックは他に移ります(アプリが十分に早ければ、ネットワークがネックになるなど)。そして、各々のレイヤで改善が進むと、最終的にボトルネックは、そのレイヤをつなぐプロトコル/フォーマットに移っていく場合があります。今回一番絡んでくるのは、「どんなに帯域とアプリが早くても、 HTTP がボトルネックになる」といったパターンです。


このレイヤ、標準プロトコル/フォーマット自体の改善は、先ほどのリストに加えて E としておきましょう。
標準仕様の改善などにあたるので、 IETFW3C などに参加することで貢献はできます。一般の技術者には敷居が高いでしょう。またステークホルダが多いので、議論も多岐にわたり、決まっても普及に時間がかかる場合が多いです。

Make the Web Faster

Google は、 Make The Web Faster というプロジェクトを実施しており、そこでは Google というポジションだからこそできる Web の改善方法の開発や、仕様の提案を行っています。(以下、長いので単にプロジェクトと言ったらこれを指すとします。)


Page Speed というプロダクトは、先の A にあたります。 Apache のモジュールなどとして提供されていて、自分のアプリに取り込めば、「ハイパフォーマンス Web サイト」にあるような改善の補助をしてくれるものです。その内容を、ベストプラクティスとしてまとめたものも公開されています。


最近すっかりシェアを伸ばした Chrome が速くなるのは、 B にあたるでしょう。まあ、 Chrome の改善は Google が普通にやっていることで、 Make the Web Faster にリストされているのは、 Chrome の Analyze 機能の改善になっています。


Google が提供する DNS や CDN もプロジェクトに含まれています。 Google の強力なインフラをベースとしたもので、 C や D に含まれると言えそうです。


では E にはどういったものが含まれるのでしょうか?

Google が取り組む Protocol / Standards の改善

E の中身として Make the Web Faster には Protocol / Standards が分けてのせてあります。

Standards

Web はネットワークを介すので、送信するファイルのサイズは小さいほど有利です。そして、サイズが大きいファイルの代表が画像と動画でしょう。
WebP は、 PNGJPEG といった Standard な形式よりも、効率の良い圧縮形式です。 Facebook なんかも使い始めていますが、まだ対応したオーサリングツールなどがなくてちょっと問題になったりしています。
標準的なフォーマットを変えるのはまた難しいものですが、これもプロジェクトの一つです。
(ちなみに、動画版の WebM もあります。あまり詳しくないのですが、これはコーデック問題とかそっちが主眼みたいで、プロジェクトにはリストされていません。)


画像や動画に限らず圧縮率が高いことは有利です。圧縮を有効にすると、こまごましたミニファイが誤差程度になるほどには効率が良くなる場合があります。で、この圧縮の定番である gzip を改善したのが Zopfli です。 プロジェクトには上がっていませんが、圧縮に多少時間がかかる代わりにサイズが 3-8% 小さくなる、展開時間は同じ、というもの。圧縮は Web だけの問題領域ではありませんが、モチベーションは同じかなと思っています。


他には、 HTML5 まわりで W3C に貢献すること自体、プロジェクトの一環としても位置付けられているみたいです。(まあ、これもプロジェクトを超えて、 Google 自体の大きなミッションでしょうが。)

Protocol

先ほどの D の改善で、例えばネットワーク帯域が増えたとき、動画や大きなファイルのやり取りの改善は期待できますが、小さいファイルの集合である Web ページの読み込みの改善は限界があります。


実際 Web ページについて言えば、帯域よりも RTT の改善の方が効果が大きいことが、 Google調査からもわかっています。


RTT の改善は、要するに行って返ってくるまでの時間の短縮ですが、これは物理的な距離なども関係するので改善は難しいです。


Web ページの取得には、 DNS 名前解決、 TCP 接続(3-way-handshake)、 HTTP req/res などが必要になり、増えるほど RTT の総和は長くなるので、そもそも「RTT の数を減らす」というのが現実的なアプローチです。アプリ側でファイルを統合するなどの方法がそれにあたりますが、そもそもプロトコル自体を見なおせば、もっと減らせるかもしれません。


HTTP はそもそも、論文の共有などを目的に作られたシステムなので、設計もテキストドキュメントの共有に寄せた仕組みとなっていました。
これ自体は、重要な設計思想だったと思います。扱いやすいテキストプロトコル、スケールさせやすいステートレス性。シンプルなデザインだったからこそ、 Web はここまで普及したと言えるでしょう。


問題は、 Web 自体が十分すぎるほどに普及した今、アプリ/システム/ゲームなどのプラットフォームとして使われ、単一ドキュメントの閲覧に留まらない様々な用途に使われるようになった今現在において、そのデザインは本当に最適か?ということだと思います。


通常、標準プロトコルに手を入れるのは、接続性がなくなるために簡単にはできません。しかし、 Google は多くの Web サービスとともに、クライアントとなるブラウザも持っています。両方を備えかつユーザ規模も大きい Google は、Google のサービスに Chrome で接続するユーザにだけ、オレオレプロトコルで大規模な実証試験を行うことができたのです。

SPDY とはなんだったのか


Web の根幹を成すプロトコルに手を入れる取り組みが SPDY です。現在では ChromeGoogle のほぼすべてのサービスが対応し、大規模に運用されています。


独自プロトコルとはいっても、あまり標準から外れたパケットを流すと、 intermediaries (proxy や FW など中間に入るもの) をうまく通れない可能性があります。SPDY がデフォルトを SSL にしているのはそうした意味もあります。暗号化しちゃえば中で何が流れても中間ではわからないですし、変にいじられることもありません。また 443 は 80 と並んでほぼ通るポートです。 npn というアップグレードの仕組みも Google の提案したもので対応が多いのもあるし、そもそも Google 並のサービスだとセキュリティ的に全部 SSL の方がいいという判断も絡んでいると思いますが。


SPDY にはいろいろなアイデアが盛り込まれていますが、ここではTCP 接続の扱いに着目しましょう。
HTTP/1.0 では、毎回接続し、毎回切っていました。ドキュメントを取得して表示する用途であれば、まあ自然といえば自然です。
しかし、ページを構成するコンテンツ(CSS, JS, Image)が増えると、毎回切って 3-way-handshake からやり直すのはやはり無駄です。そこで、 HTTP/1.1 では Keep-Alive で確立した TCP 接続を使いまわすようになりました。
使いまわすといっても、繋ぎっぱなしは負荷が増えるので、ページのコンテンツ全部を落としたら切断したいところです。しかし、ページ単位でのライフサイクルの管理は容易ではなく、 Apache などでは「時間」「アクセス回数」などのわかりやすい指標で設定されているのが現状のようです。


あと、せっかく使いまわせても、前のレスポンスが終わらないと次のリクエストを投げられないという仕様があり、 1 本のリクエストを使いまわすと逆に遅くなる場合がありました。これを解決するのが pipelining という仕様だったのですが、対応が難しく、しかも対応していないサイトは崩れることがあったため、ブラウザもオフのものが多かったのです(Opera は有効だったけど、無効にしているユーザが多いみたい)。
また、やったところでそんなに速くならないという話もあったり。


pipelining は10 年近くたっても普及しきらず、ブラウザベンダはたくさんの TCP 接続(6 本がメジャー)を同時に確立することで並行してコンテンツを取るように実装しました。仕様では、同一サイトには 2 本位にしようね、という推奨があるのですが、守っていると他のブラウザより「遅い」というレッテルを張られかねないので、ベンダとしてはしょうがない選択だったのでしょう。(よって 1 ドメインには 6 本までの制限ですが、別ドメインだともう 6 本確立できます。静的ファイルなどはサブドメインや別ドメインのCDN に置きましょうという最適化手法はここからきます。)


SPDY は、 1 本の接続を極力使い切る設計になっています。具体的には、コネクションの上に「ストリーム」という論理的な接続を作り、それは多重化されています。たとえば 3 つのコンテンツの取得は 3 つのストリームを確立して行い、取得が終わっても終わるのはストリームでコネクションはそのままですし、ストリームの順番も自由なのでたくさん接続を作る必要もありません(理想は)。 Keep-Alive + Pipelining + α なイメージです。


あと、一本の TCP 接続を使い続けることは、 TCP の性質上も有利です。
TCP は、輻輳制御のため、最初は小さいパケットを送り、送るたびにそのサイズを増やしていく Slow Start という仕組みがあります。接続を毎回やり直すと、パケットサイズも毎回リセットしてしまいます。使いまわせば、送れば送るほどコネクションが温まって、輻輳が起きるまではパケットサイズが増えて効率がよくなります。


さて TCP を使いまわすという点では SPDY はだいぶ効率が良くなったと思います。でも、それって「接続が確立した後」の話ですよね。ただユーザにとっては「一番最初」の表示もやっぱり重要です。
Google は SPDY 以外にも、 TCP の層にまで下りた改善提案もあります。
例えば、 TCP の 3-way-handshake を Cookie を使って 1 回省略する TCP Fast Open という仕様や、送信する最初のパケットサイズを大きくする Increasing Initial Congestion Window などがそれにあたります(これもプロジェクトに入っています)。
実際は SPDY のレイヤだけでなく、 TCP のレイヤにも手を入れたいのが本音ですね。

TCP とはなんだったのか


TCP にも手を入れたいと考えた時点で、やっぱり TCP も HTTP と同様に「現在のニーズに合わないデザインなのかも」という疑問を持つのが正しい考え方なのかもしれません。
じゃあ、 TCP のデザインってなんだったでしょう?


自分のように、ネットワークをインター博士 に学んだ人なら、 TCP は「正確・確実」であると教え込まれたでしょう。
その通りで、 TCP の 3-way-handshake も輻輳制御も、ネットワークを通じて確実にデータを届けるための仕組みです。これがあったから、今ほどネットワークが良くない時代でも、データは確実にクライアントに届きました。「正確・確実」を実現するためにチェックやリトライの仕組みを持っていたのです。


SPDY はそんな TCP の上に多重化の仕組みを設けました。つまり、どんなにストリームを多重化しても、パケットレベルで落ちれば再送が走るし、輻輳が起きればパケットサイズは下がってしまいます。(HTTPでたくさん接続を作っていた頃は、一個の接続の影響は他には出なかったのに。)


3-way-handshake もなんとかならないものでしょうか、 Fast Open で速くなるのは Cookie ができた後、つまり本当に初対面のサーバとは無理なんですよね。


しかも、 TCP レイヤの改善は影響が大きいし、いじれる余地も少ない、なにより OS レベルの対応などになるので、普及にも時間がかかります(先の二つはもうカーネルには入っていますが、 Windows には無いです)。


そもそも「TCP の上に多重化レイヤ」という発想自体は、ネットワークプログラミングの視点から見ると筋の良いものではないといえます。TCP自体の性質のために、いろいろ不自由が出てしまうし、劇的な改善も見込みにくい。

そして QUIC へ


そこで、 GoogleTCP ではなく UDP の上に Web を構築するという方針にも取り組み始めました。それが QUIC です。


UDP は、ご存じのとおり信頼性を担保するレイヤがありません。とにかく送りつけて、後はしらんというような仕組みです。そのため、映像の配信のような「ちょっとくらい欠けてもいいからどんどん送る」という用途なんかに使われるという説明が多いでしょう。


さすがにそのままだと、安定した Web の提供はできません。そこで QUIC は、独自に信頼性を確保するレイヤを UDP の上に構築しています。
具体的には、 TCP のようにストリーム全体に影響がないような輻輳制御や、再送を減らすための誤り訂正の仕組みです。
また、先の理由と同じく全体を暗号化するレイヤも自分で持っています。
その上に、多重化のレイヤを構築して、 SPDY を提供することによって、 TCPボトルネックになっていた部分を改善して、 Web を提供できるのです。
(実際に QUIC を 443 ポートを通して、 HTTPS 上で提供できるようにするための実装が、Chromium では始まっているようです。)


つまり、 QUIC は SPDY over QUIC over UDPという手法をとることで、 SPDY over TCP の限界を突破するために考えられたプロトコルです。


公式にでたドキュメントからも、 QUIC が SPDY をまねた言葉遊び先行の Play Project ではなく、本気で Make the Web Faster を考えた上にたどり着いたプロトコルだと考えるのも、無理はないのではないでしょうか?


ちなみに、この改善の効果は未知数です、Google も完全に実装が終わっているわけではないようなのですが、 Google のユーザの多いサービス群と、シェアの大きい Chrome を合わせてそのうちテストが始まるでしょう。
(今は、 SPDY-Indicator も QUIC に反応できるようになっているので、もし QUIC サービスに気が付いたら教えていただけると幸いです。)

「なぜ出てきたのか」からの学び


QUIC は、それこそまだ Google のオレオレプロトコルです。 Google 自身もこれを標準にするかどうかといったところまでまだ考えてはいないでしょう。実績も効果も未知数ですし、実際にやってみないと本当に価値があるかはわからないのが本音だと思います。


同じように、他にも色々な改善案が Google 社内では動いているのかもしれません。


Make the Web Faster は Google が本気で Web を考えて取り組んだ成果が詰まっています。今すぐ取り込めるプラクティスもあれば、一般の開発者じゃ手が出しにくい Standard や Protocol にも大きなリソースを割いています。
そして、使わなくてもこうしたプロジェクトを知ることで、 Web が持つ様々な面(良さ、欠点)が見えてきます。


それがどういうデザインで、効果がどうかという点ももちろん重要です。
すぐ使えるか、対応はどうか、みんなが使っているかというのももちろん重要です。
でも、もう一つの側面として、なんでそんなものが出てくるのか?という視点を持つと、またいろいろ見えてくるなぁと。


で、今回は SPDY/QUIC 周りを見て思ったことを、連休のノリでなんとなく書いてみたところ話が伸びて、また長くなってしまったなぁという、、

Web+DB Press vol.75 で SPDY/HTTP2.0 特集を書かせて頂きました

intro

タイトルのとおり、 Web+DB Press の vol.75 に

Web をより速くする次世代プロトコル!![速習]SPDY & HTTP/2.0

というタイトルで特集記事を書かせていただきました。

WEB+DB PRESS Vol.75

WEB+DB PRESS Vol.75

SPDY 特集

本特集は、 Make the Web Faster という取り組みの一貫として、Google が開発している、新しいネットワークプロトコル SPDY について書いています。章立ては以下のようになっています。


第1章:次世代プロトコルSPDY: GoogleがしかけるWebの高速化プロジェクト
第2章:SPDYの仕様と周辺ツール: プロトコルを知り,使いこなそう
第3章:SPDYの導入方法: 自分のサイトをSPDY対応するには
第4章:そしてHTTP/2.0へ: 見直される標準仕様とSPDYの影響

内容

今回、特集を通して解説する SPDY のバージョンは SPDY/3 です。

1章

SPDY のモチベーションを知るために HTTP とその下の TCP についておさらいします。
つまり、ネットワークプログラミングの基礎的な部分の話ですね。
すると、現在の Web の状況と照らしあわせた時にボトルネックが見てきます。
それを踏まえて、 SPDY はそれらをどう改善しているのか?という切り口で解説しました。

2章

SPDY のプロトコル仕様をより詳細に解説します。
フレームの簡単な構造と、それらが実際にやり取りする様を Spdylay という SPDYer(?) 必携ライブラリに付属する Spdycat というツールを用いて可視化しながら解説します。

3章

「自分のサイトを SPDY に対応する」というテーマで、 Apache mod_spdy, Nginx, node-spdy の 3 つの導入方法を解説します。mod_spdy と node-spdy は Server Push にも対応しているため、その設定方法についても触れています。
また、 SPDY にすれば必ず早くなるとは限らないため、 SPDY に対応するにあたり考慮すべき点などのノウハウについても、現在わかっている範囲で解説しています。

4章

去年 IETF で策定が開始された、 HTTP の次世代規格 HTTP/2.0 (draft-0 から draft-1 くらいまで)の解説です。
HTTP/2.0 は最初のドラフトに SPDY/3 が採用され、また後続の仕様議論にも SPDY/3 が大きく影響を与えているため、
この二つは非常に重要な関係にあります。
そこで、 SPDY/3 には解説を踏まえた上で、なぜ SPDY が選ばれ、HTTP/2.0 はどういう方向に進んでいるのか、両者の立ち位置はどう観るべきなのか、などといった点を現時点で筆者が把握している範囲で書きました。

今後

現時点でも SPDY は SPDY/4 が、 HTTP/2.0 は draft-3 あたりが進んでいます。
IETF も interim がありましたし、その意味ではこの雑誌が出る時点で「最新」ではない話も含まれているのが正直なところです。


しかし、これは同時に SPDY, HTTP2 の発展が早く、議論が盛り上がっていることを意味しており、それは最初から想定していました。


なので、今回の特集では SPDY や HTTP2 が「何がしたいのか?」というモチベーションの部分に注目することを意識したつもりです。


この特集を読むことで、「ここまで」を把握して、興味があれば「これから」を追いかける上で、土台となるような記事になれば幸いです。

謝辞

かなりの遅筆になってしまい、担当の稲尾さんには終始迷惑をかけまくってしまいました。
最後まで根気強く付き合って頂いたおかげで、この記事はあります。感謝してもしきれません。


また、自分の追いきれていない知識について、的確なツッコミを入れて下さったレビュアーの方々にも、非常に感謝しています。


みなさま本当にありがとうございました!

まとめ

このブログを見てくださる方々は、定期的に買っている方が多いかもしれませんが、Web+DB Press は、今月も自分の以外にも面白そうな記事が多いです。


その中の 1 つとして、是非読んでみて頂けるとありがたいです。
フィードバックも歓迎します。よろしくお願いいたします。

おまけ

同日に Web+DB Press の総集編が発売されます。
vol.1 - vol.72 までが収録されており、豪華な執筆陣による書きおろし記事もあります。
(ちなみに vol.71 には、自分も共著で書かせていただいたい WebSocket 特集もあります。)


合わせてどうぞ !!

WEB+DB PRESS 総集編〔Vol.1~72〕 (WEB+DB PRESS plus)

WEB+DB PRESS 総集編〔Vol.1~72〕 (WEB+DB PRESS plus)

Apache mod_spdy の X-Associated-Content で Server Push

intro

SPDY の Server Push については以前にも書きましたのでそちらをご参照下さい。

SPDY と WebSocket の基礎と SPDY の Push - Block Rockin’ Codes


上記記事ではサンプルの実装に node-spdy を用いましたが、更なる検証のために他の実装を調べました。


主な SPDY 実装で、 Server Push を実装しているサーバは、把握してる範囲では以下のような状況です。


今回は Server Push の検証のために、 Apache mod_spdy でこの機能を有効にする方法を調べました。

Apache mod_spdy

名前の通り、 Apache HTTP Server を SPDY 対応させるためのモジュールです。

mod-spdy - Apache SPDY module - Google Project Hosting


mod_spdy 自体のインストールはこちらを参照下さい。

Apache mod_spdy のインストール - Qiita [キータ]


そして、 mod_spdy で Server Push を行う方法は、基本的には本家の wiki である下記に書かれているんですが、具体的な方法の情報が少なかったので書いておきます。


https://code.google.com/p/mod-spdy/wiki/OptimizingForSpdy#Using_SPDY_server_push

X-Associated-Content

Server Push するリソースは X-Associated-Content というヘッダで指定します。
ヘッダのフォーマットは以下のようなものです。

X-Associated-Content: "https://www.example.com/styles/foo.css",
                      "/scripts/bar.js?q=4":2,
                      "https://www.example.com/images/baz.png": 5,
                      "https://www.example.com/generate_image.php?w=32&h=24"


mod_spdy は、この X-Associated-Content ヘッダを見つけると、そこに指定されたリソースをクライアントに push します。
フォーマットルールは以下です。

  • リソースは絶対パス指定、相対パスは非対応。ホストまでは省略可
  • 各々をダブルクオートで囲む
  • 複数ある場合はカンマ区切り
  • コロンの次に priority(0-7) を指定できる


注意点は以下です。

  • X-Associated-Content ヘッダは mod_spdy で処理されると削除される(クライアントには届かない)
  • priority が指定されなかった場合は、現実的かつ最小の値が自動で付与される(実装依存)
  • priority は値が小さい方が優先順位が高い


以上より、 mod_spdy が処理する前のどこかの処理で、レスポンスヘッダに X-Associated-Content ヘッダを付与してあげれば、mod_spdy が push を行ってくれます。
方法としては CGI などでプログラムで行うか、 mod_headers を用いることで実現できます。 

mod_headers

Apache のモジュールだけで完結し、デフォルトで入ってることから mod_headers を用いる方法が一番手軽です。
mod_headers はそのなの通りヘッダを制御するモジュールで、設定ファイルのほとんど全ての場所で、のヘッダを操作できます。


では、 /spdy/test/push.html に、 /jquery.js と /bootstarp.css を push する設定を作成してみます。

<Directory /spdy/test>
  Options Indexes
  allow from all
  <Files push.html>
    Header append x-associated-content "\"/jquery.js\", \"/bootstrap.css\""
  </Files>
</Directory>

ダブルクオートのエスケープに気をつければそのまま書くだけです。

成功したら、 Chrome などで jquery.js と bootstrap.css が Cache から読み込まれていることを確認して下さい。

Rails

とにかく mod_spdy に渡る前に X-Associated-Content ヘッダが付与できれば良いので、プログラムを介す場合はそのプログラムから API 経由でレスポンスをいじれば同様のことができます。
RailsApache で走らせている場合は以下のような感じ。(参考)

class SPDYController < ApplicationController
  def server_push
    response.headers["X-Associated-Content"] = '"/assets/jquery.js", "/assets/bootstrap.css"'
  end
end

CGI なども同様です。

outro

SPDY 単体でもそうですが、 Server Push も含めるとサイトの最適化に対する選択肢が増えます。


特に「ハイパフォーマンス Web サイト」に書かれているような手法のいくつかは、SPDY によって見直す余地が出てくる可能性があります。


現在その辺を少し検証しているので、まとめたらまた書きたいと思います。

GO の SPDY パッケージのアップグレード

追記

2013/02/13
パッチが本家に取り込まれました

https://code.google.com/p/go/source/detail?r=71409a1c89f0&repo=net

レビューでもの凄くお世話になった mikio 先生には頭が上がりません。
本当にありがとうございました。

intro

あけましておめでとうございます。
このお正月は、ずっと Go を触りながら、 Go の準標準モジュール? である SPDY パッケージのアップグレードをやっていました。


もともとは、 HTTP2 のサーバを書いてみようと思い、色々あって Go を選んだら、spdy パッケージがあるけどバージョンが古かったというのが始まりです。


SPDY の知識はある程度ありますが、 Go 自体はほとんどはじめてなので、こっから Go にも詳しくなれればというモチベーションです。

Go の SPDY パッケージ

もともと、 spdy や websocket などのパッケージは Go の標準パッケージだったんですが、Go の version 1 が出るタイミングでサブリポジトリに移されたようです。
(でも、管理自体は Golang Project がやっているみたい。)

http://golang.org/doc/go1.html#subrepo

なので、 import するときは下記のように指定します。

import "code.google.com/p/go.net/spdy"


このパッケージが提供するのは、 SPDY の各フレームに対応した型とその型への write/read のインタフェースの実装です。


で、この spdy パッケージは spdy/2 準拠になっています。これを spdy/3 にするというのが今回のスコープ。

成果

spdy/2 から spdy/3 への変化は色々ありますが、このパッケージに関わる大きな変化は以下です。

  • 圧縮に使う zlib の辞書データ
  • NOOP frame が消えた
  • CREDENTIAL frame が増えた
  • 各 frame の定義がちょこちょこ変わった


ということで、これらを実装したんですが CREDENTIAL frame 以外は実装が終わりました。


(CREDENTIAL frame はドキュメントの記述が他と整合して無く、内容も割と半端で、よくわからないところがあるし、しかも次のバージョンでは消えるかもしれない、ということでちょっと後回しになってる)


あとは、テストを直しながら明らかに SPDY の仕様変更に弱すぎるところがあるので、そこはペンディングにしたという点を除いては、一通り終わったかなと。
(ほとんどが、 Go のリーディングに費やされました。)

ソースはとりあえず下記に上げています。

https://github.com/Jxck/go-spdy

Contribute

最終的には本家に取り込んでもらえればと思うので、そのための手順を踏む必要があります。
手順は以下。

http://golang.org/doc/contribute.html


とりあえず ML でやってることの旨を伝えたら、Welcome とのことでした。
なので、あとはこの流儀に沿って本家に投げていこうと思います。


Git じゃなくて Mercurial 必須なんで、そっからですが、ちゃんとやれば Go のコミッタ達にレビューをしてもらえるということなので、十分得る物があるだろうと。

Go を触ってみて

今回の作業歴=Go 歴な訳ですが、個人的な感想を箇条書きで。

go fmt

go fmt が最初からあるのは良い。そして、そんなに違和感のあるフォーマットでもなかったし。
こういう流派で無駄な争いやらがおこるのってホント無駄なんで、公式が(長ったらしい説明でなく)ツールで提供してしまうので良いと思う。

ちなみに vimプラグインとかも提供されてて、コード書く環境自体に迷いは無く始められた。

go test

test がパッケージもコマンドもも最初から組み込まれているので、今一番生きのいい testing FW を探すというこの上なく無駄な時間が省けるのもいいですね。


test パッケージくらい最初からある言語は多いけど、ベンチやらコマンドやらも込みで、テスト関数やテストファイルの命名も決まっていてあとは書くだけっていうのがいいと思います。


ただ、 test にはちょっと癖があって、いわゆる assert.Equals な検証ではなく、 Go のコード自体に頼っておかしかったら落とす(Fail) という点が割と面白い。
比較に使うのは、 reflect と型アサーションが多いみたい。

  // 型アサーション
  v, ok := x.(T)
  if !ok {
    t.Fatal("Incorrect type:", T)
  }
  // 同値検証
  if !reflect.DeepEqual(expected, actual) {
    t.Fatal("got: ", actual, "\nwant: ", expected)
  }


あとテストを指定する -test.run という直感的じゃないオプションという点(というか go のオプションパーサのせいで、全体的にコマンドが UNIX ぽくない)と落ちたテストの関数名とかの出し方が -v だってことを覚えておけばまあいいかと。


細かいけど、型があるために Fixture 的なものを作る時にごまかしが効かないというか、 Ruby や JS ではテストしたいところに合わせた半端なオブジェクトをでっち上げたりできたけど、そういうことが出来ないなと思った。
別に、出来ないなと思っただけで GO が悪いとかそういうことは無い。単なる感想。
型があるために減るテストもあるし、Mock みたいな仕組みもあるらしいので、その辺を上手く使って行きたい。

go run

これがあるのが、最大の強みかなと思う。それが無ければちょっと便利な C とか C++ になるのかもしれないけど、ちょっと走らせるという点のコストの低さが非常に嬉しい。


同じコマンド体系で go build もできるので、すぐにバイナリもできるし。この辺がモダンだなぁと思う。
(複雑になってきたら、やっぱり make を書くのかな?その辺は知らない)


ただ、ちょっと試したい時にも、 import や変数の不使用チェックが必ず行われるのがちょっときつい。
カジュアルにコメントアウトしただけでは動かないことがあるので、 go run の時だけでもオプションが欲しいところだけど、
そういうことはしないで、 _ (アンダースコア) を使うようにお達しが出ている。

http://golang.org/doc/go_faq.html#unused_variables_and_imports

むしろ、run でオプションにしておいて build 時にはエラーにしちゃう方が、消し忘れなくていいと思うんだけどどうなんだろう。

GOPATH

最初よくわからずにハマった。全てはこれをきちっと設定してあげる事が重要。ここが規約になっていることが、 make みたいなツールが無くても go build/go install で色々解決できる助けになっているよう。(build のプロセスはまだブラックボックスでいる)


ちなみに、ここはプロジェクトをまたぐと設定しなおさないといけないのが面倒。
それをはかどらせるツールはある(Goのレポジトリ管理をするgenvというものを作りました - YAMAGUCHI::weblog) が、今回はプロジェクトが一個だし以下だけで済んだので入れていない。そのうち色々やるようになったら入れよう。

export GOPATH=$HOME/path-to-project/spdy-go
export PATH=$PATH:$GOPATH/bin
名前空間

パッケージを分けて、大文字で始まる関数がパブリックという覚えやすいルールなんだけど、慣れないと迷う(迷子になる)。


パッケージが複数のファイルから構成されていて、それを構成するファイルの命名規則は無いので、ある関数がどこで定義されているかは、 grep しないとわからない。ファイル自体がモジュールになるのはそれはそれで利点だったなとも思った。


今回のパッケージは、大きく 3 つにわかれていて、型(ベースとなるクラス的な)、 Read、 Write とあるけど、この分け方から外れる帯域定数とかは、grep しないとわからない。まあ、 Java とかも似た感じだけど eclipse があるから困らなかったのか。型と IDE の相性がここで出てくるかも。
あとは、慣れだと思う。

その他

思い出したら後で書く。



ということで、しばらくはこのパッケージのコントリビュートに取り組みたいと思います。

これからの Web の話をしよう。 (次世代 Web セッション @ CROSS2013)

update

2013/1/13
終了したので録画やログを追加

intro

2013/1/18(Fri) に開催される CROSS2013 にて、「次世代 Web セッション」というセッションを担当させていただくことになりました。


次世代 Web セッション


今日はこのセッションの内容と、このセッションで自分がやりたいと思っていることについて書こうと思います。

Theme

このセッションは「次世代 Web セッション」というタイトルとし、主にいま起こっている Web の変化(リアルタイム Web, HTTP2.0 の登場 など)について、

  • 「何が起こっているのか」
  • 「どこに向かっているのか」


を、


の 2 つのセッションに分けて議論したいと思っています。
(枠自体は 「次世代 Web セッション」の 1 つですが、内容的には 2 つのセッションからなります)

Motivation

HTTP, CGI, Ajax, HTML5 etc と、 Web には今までもいろいろな変化がありました。そして今また、 Web が大きく変わりつつあると感じています。


この変化をキチンと把握するのはなかなか難しいです。


例えば「WebSocket とは?」といった部分的話は割りとしやすいので、初心者向けの話は多くのイベントでされています。 一方で、そうした初心者向けの話は、もう聞き飽きている人も多くいます。 しかし、初心者向けセッションの「その先」を扱うのは実は結構難しいのが現実です。


今回の CROSS では各 1 時間という時間をつかって、初心者向けセッションで語られない「その先」に挑戦したいと思っています。


「Web がどうなるか」に答えを持っている人はいません。しかし、僕ら技術者はそこにコミットすることはできると思います。


「どこに向かっているのか」を考えるには、まず今「なにが起こっているか」をきちんと把握する事も必要です。


そこで自分は

  • 「何が起こっているのか」
  • 「どこに向かっているのか」


について、きちんと議論する場を作りたいと思い、それの議論ができるであろう方々に、声をかけさせて頂きました。

プロトコル編」(14:00-15:00)

今起こっている変化の主流には、プロトコルレベルで Web を見直すという取り組みが大きく関わっていると考えます。


そこでは様々なステークホルダが参加しているので、議論される問題は Web の現状を浮き彫りにし、非常に興味深いものがあります。


プロトコル編では、主に Web のプロトコル自体の変化(WebSocket, SPDY, WebRTC, HTTP2.0 etc)について、低レイヤで何が起こり、どこに向かっているかを議論したいと考えています。

登壇者
  • 小松さん(@komasshu)
  • 大津さん(@jovi0608)
  • 清水さん(@kazubu)

アーキテクチャ編」(15:15-16:15)

プロトコルが変わると、アーキテクチャが前提としていた制約が変わります。 すると、自ずとアーキテクチャも見直す必要が出てきます。


また、プロトコル以外にも、サービスに求められる要件の変化によっても、アーキテクチャは変化しています。


アーキテクチャ編」では、そうしたプロトコルの変化、時代の要求の変化により、Web のアーキテクチャがどうなっていくだろうかという点について、議論したいと考えています。
キーワードとしては REST や MVC、リアルタイム、リアクティブ、バイナリベース/テキストベースなどを考えています。 ただ、キーワードはあくまで議論の呼び水であり、議論の主軸は「何が起こり、どこに向かっているのか」です。

登壇者
  • 山本さん (@yohei)
  • 江島さん (@kenn)
  • 佐々木さん (@yssk22)

扱わない内容

今回は、各セッションが 1 時間しかありません。 これは、ちょっと真面目に議論すればあっという間に過ぎてしまうと思います。
その限られた時間の中でとにかくテーマに集中するために、いくつか切り捨てる内容について書きたいと思います。


これは、自分が今回「あまり積極的に扱う必要がない」だろうと考えているものです。 といってもさじ加減なので、実際は登壇者の方々に委ねます。
しかし、参加者の方には「前提」として考えていただきたいと思っています。

初心者向け内容

難しいところですが、例えば「WebSocket とは何か?」「REST とは何か?」「IETF とは何か?」etc といった話は要らないと思っています。
知識を得て Catch Up するためではなく、議論を通して Keep Up するセッションにしたいという思いがあります。

過去の事

今回、テーマにはあえて「過去」を入れていません。 懐古するためのセッションとは考えていません。

  • 「何が起こっているのか」(現在)
  • 「どこに向かっているのか」(未来)


もちろん、古きを知ることは重要です。 Web の歴史、HTTP の歴史 etc 引き合いに出るでしょう。
しかし、過去を改めてから未来を語るには時間がたりません。過去は基本的には共有された前提として考えて、それらを踏まえた「その先」を中心に議論したいと考えています。

登壇者紹介

特に自己紹介で大きく時間を使ってしまうセッションが多いです。
今回の登壇者のみなさんは著名な方が多く、このセッションを聞きに来る方は知っている人が多いと思うので、冒頭に自分がみなさんの名前を紹介する程度とさせて頂きます。


各登壇者の紹介は、 セッション概要 から見ることもできますので。予め見ておいて頂けると良いと思います。

進め方

流れを決めすぎると予定調和になってしまうので、打ち合わせの段階でおおまかな方向性とキーワードのみを決めておき、
当日はそれについて基本的にはフリースタイルで議論を進めていきたいと思っています。


あまりズレて行くなら、途中で切るなどはしまが、その場で起こる議論をなによりも大事にしたいです。

最後に

今のWeb について

  • 「何が起こっているのか」
  • 「どこに向かっているのか」


に 1 時間フォーカスし続けたいです。 「その話はもう知ってるよ」とか、「何度も聞いたよ」みたいな話を無くして、少しでも議論の密度を高めたいです。
そのために参加者には「前提」を求める部分が多くなる点はありますが、限りある時間を有効に使うためにご理解ください。
これだけの方が揃ったセッションなので、変わりゆく Web の今後を考える上で、少しでも熱く有益な議論ができる場を作れればと考えています。



CROSS には、このセッション以外にも興味深いセッションが多数あります。
現在エンジニアや、それに関わることを何かしらをしていれば、気になるセッションがきっと一つはあると思います。
なにとぞよろしくお願い致します。

本番終了後ログ

無事本番を終えました。
自分としては、上記に望んでいたセッションができたので満足しています。


以下が録画です。


(前半) プロトコル編


(後半) アーキテクチャ編


スライド

最後の yohei さんの一言「あとは自分の頭で考えろ」が何よりのまとめです。
そして、それを考えるに足るだけのエッセンスはほぼ出てきました、
来ていただいたみなさんにとっても、これからの Web を考えるきっかけになったなら、よかったと思います。


今回のセッションを作るにあたっては、(最終的には登壇もして頂いたんですがw) t_wada さんに色々な面でアドバイスを頂きました。
こうしたセッションを作るには自分はまだまだ力不足だったので、非常に心強かったです。


そして、このセッションのために非常に豪華な登壇者の方に集まって頂きました。
みなさん忙しい中自分のわがままに付き合って頂いて、本当に感謝しております。


最後に muddy さんを始め運営のみなさん、このような機会を頂き本当にありがとうございました。


Jxck