{ "cells": [ { "cell_type": "markdown", "metadata": { "heading_collapsed": true, "slideshow": { "slide_type": "slide" } }, "source": [ "# このスライドへのアクセス方法\n", "\n", "1. 「nbviewer.jupyter.org」というサイトへアクセス\n", "2. 「mrsekut」で検索\n", "3. 「slides > HTTP2.ipynb」\n", "4. 右上のプレゼントマークでスライドっぽく表示\n", "5. スペースキーで順番に移動\n", "\n", "[リンク](http://nbviewer.jupyter.org/format/slides/github/mrsekut/slides/blob/master/HTTP2.ipynb#/)\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# HTTP/2.0について\n", "\n", "tryangle株式会社 \n", "丸末皓太" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# 自己紹介\n", "\n", "### 丸末皓太\n", "- 大阪府立大学 数学課(いちおうたぶん2回生)\n", "- 休学中\n", "- 府大生向けの「Opulency」というアプリを作った\n", "- 現在はtryangle社でばりばりアプリ開発してる卍卍\n", " - 主にフロントエンド\n", "- 最近興味あること\n", " - Typescript: ReactNative\n", " - Haskell: 関数型プログラミング\n", " - Go: ネットワーク, プログラミング言語そのもの\n", " - Rust: OSなどの低レイヤ\n", " - テスト \n", "\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "notes" } }, "source": [ "- 大学に入ってから本格的にプログラミングを始めた\n", "- 1回生でprogateなどでhtml,cssとか、普通にvimとか触った\n", "- 2回生になって機械学習の勉強を始めたり、reactでopulencyというアプリを作り始めた\n", "- opulencyは今年の4月にリリースして2週間で500人くらいにいれてもらったが、リリースした瞬間にモチベが切れ、終わった" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "![mrsekut](https://github.com/mrsekut/myStorage/blob/master/img/mrsekut_circle.png?raw=true)\n", "\n", "### SNS\n", "- blog: [mrsekutの備忘録 (http://mrsekut.site/)](http://mrsekut.site/)\n", "- twitter: [@mrsekut](https://twitter.com/mrsekut)\n", "- github: [mrsekut](https://github.com/mrsekut)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# 発表のながれ\n", "\n", "1. 発表の動機と目的 (0.2m)\n", "1. 従来のHTTP (3m)\n", "1. HTTP/2の概要 (15m)\n", "1. 比較のデモページ (1m)\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "# なんでHTTP/2について調べてみたか\n", "\n", "- ネットワーク全然しらないなーってなった\n", "- これまでの勉強会で「webを支える技術」などを参考に勉強\n", "- 「Real World HTTP」という本を買ってもらった" ] }, { "cell_type": "markdown", "metadata": { "heading_collapsed": true, "slideshow": { "slide_type": "slide" } }, "source": [ "# 発表の目的\n", "\n", "- 浅く広く紹介します\n", "- キーワードを拾っていってもらえばと思います" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# 従来のHTTP\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## 概要\n", "\n", "- 通信プロトコル\n", " - ステートレス性\n", "- リクエストとレスポンス\n", "- RFCという提案書\n", " - IETFという団体が管理\n", "- HTTP/0.9 (1991~)\n", " - GETしかない\n", "- HTTP/1.0 (1995~)\n", "- HTTP/1.1 (1997~)\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "notes" } }, "source": [ "- 0.9, 1.0, 1.1とバージョンが上がり、今の最新は2.0\n", "- たとえばhttp/1.1はRFC2068として初版が発表" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## HTTP1.1の課題\n", "\n", "- リクエストの多重化\n", " - ページが大きくなり必要なリソースが増えた\n", " - 1RTTで1リクエスト/1レスポンスしかできない\n", "- パイプライン化\n", " - 同時に複数のリクエストを送れるようになった\n", " - しかし、同じ順序でレスポンスしないといけない\n", " - HoL(Head of Line)ブロッキング問題\n", " - ![wikiから引用](https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/HTTP_pipelining2.svg/640px-HTTP_pipelining2.svg.png)\n", " - 画像引用元: [HTTPパイプライン - Wikipedia](https://ja.wikipedia.org/wiki/HTTP%E3%83%91%E3%82%A4%E3%83%97%E3%83%A9%E3%82%A4%E3%83%B3)\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "notes" } }, "source": [ "- パイプライン化\n", " - らうんどとりっぷでぃれいたいむ\n", " - 前回のリクエストの完了を待たずに次のリクエストを送れるようになった\n", " - \n", " - 一つ処理に時間がかかるものがあると、後続のレスポンスは全てブロックされる\n", " - これをHoLブロッキング問題と呼ぶ" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# HTTP/2の概要" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## 誕生の背景\n", "\n", "- アクセスの増加\n", "- 2015年2月17日発表\n", " - HTTP/1.1から16年ぶりの改訂\n", "- GoogleのSPDYから生まれた\n", "- 当初のプロジェクトの目標はページ読み込み時間の50%減" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "notes" } }, "source": [ "- LTEなどの普及によりエンドユーザーの通信速度は上昇したが、サーバー側のページロードの速度はそれに比例せず1.6Mbpsほどで頭打ちしていた\n", "- 2009年からgoogleが独自にweb高速化の取り組みの一環からSPDYというプロトコルを作っていた\n", " - Twitter,Facebookでも使われるようになった\n", " - HTTP/2はこのSPDYを改良したもの" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## HTTP/2の特徴\n", "\n", "- ヘッダの圧縮\n", "- リクエストの多重化\n", "- リクエストの優先度制御\n", "- サーバープッシュ\n", "- バイナリプロトコル\n", "- フロー制御" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### ヘッダの圧縮" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### 一言で言うと... \n", "→ いろんな方法でリクエストやレスポンスのヘッダを圧縮する" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### ヘッダの圧縮\n", "\n", "\n", "- ヘッダー圧縮\n", " - 従来の圧縮に加え、ヘッダ部分の圧縮ができる\n", " - 静的テーブル、動的テーブル\n", " - 使用頻度の高いヘッダ、一度送信したヘッダなどに番号を振り、次からそれを使う\n", " - HPACK\n", " - 動的に辞書を更新し、2回目移行はインデックスを用いる\n", " - 文字列をHuffman Encodingによって圧縮\n", " - 高頻度で用いられる文字を少ないビット数で表現する\n", " - バイナリ形式\n", " - [超わかりやすい解説記事](https://qiita.com/iwanaga/items/98f60003c0114e04095e)\n", " - [超詳しい解説記事](http://syucream.github.io/hpack-spec-ja/rfc7541-ja.html)\n", " - [アルゴリズムの解説記事](http://www.techiedelight.com/huffman-coding/)\n", " - 差分のみを送信する\n", " - [わかりやすいヘッダの解説記事](https://qiita.com/0xfffffff7/items/39b944e3845ab3776b63)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### こんなアルゴリズム" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "\n", "\n", "![](https://i0.wp.com/www.techiedelight.com/wp-content/uploads/2016/11/Huffman-Coding-1.png?zoom=2&resize=395%2C85&ssl=1)\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "![](https://i2.wp.com/www.techiedelight.com/wp-content/uploads/2016/11/Huffman-Coding-3.png?zoom=2&resize=412%2C189&ssl=1)\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "![](https://i1.wp.com/www.techiedelight.com/wp-content/uploads/2016/11/Huffman-Coding-4.png?zoom=2&resize=354%2C231&ssl=1)\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "![haffman encoding](https://i2.wp.com/www.techiedelight.com/wp-content/uploads/2016/11/Huffman-Coding-6.png?zoom=2&resize=404%2C392&ssl=1)\n", "\n", "- 画像引用元: [Huffman Coding Compression Algorithm - Techie Delight](http://www.techiedelight.com/huffman-coding/)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "notes" } }, "source": [ "- HTTP/1.1のヘッダは大きい\n", " - リクエストは最低でも300Byte程度\n", " - Cookieなどで更に増える\n", " \n", "- HTTP/1.1ではbodyをエンコードするのにgzipでサイズを圧縮する機構がある\n", " - CRIMEという攻撃手法に備えるためヘッダの圧縮には使えない\n", "\n", "- 膨大なHTTPリクエスト/レスポンスのログのヘッダの文字の出現頻度を集計し、ハフマンツリーを作成\n", "- 高頻度で使われる文字列とは母音とか\n", " - たとえばaとかが普通にすると8bit必要だったけど、例えば01みたいな2bitで耐える\n", " - 「\\(バックスラッシュ)」とかあまり使われない文字は19bitとか必要になり、逆に増える\n", "\n", "- この「ヘッダ圧縮」だけ取り上げて深めてみても面白そうなトピックだなと感じた\n", "\n", "- ちなみに「hpack」で検索するとhaskellのツールがでてくるが 、コレは関係ない\n", " - jsでいうpackage.json的なファイルからコンパイルしたりするファイルを作成するやつ\n", " \n", " \n", " " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### リクエストとレスポンスの多重化" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### 一言で言うと...\n", "\n", "→ 1回でたくさんリクエストを送っても耐える\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### リクエストとレスポンスの多重化\n", "\n", "- 1つの接続上にストリームという仮想的な双方向シーケンスを作り多重化\n", "- 同時に100以上のリクエストを送信可能\n", "- 並列に扱うことができる\n", " - レスポンスの順序に制限なし\n", " - HoLブロッキング問題を解決\n", "- データにはフレームという単位にわけられ、ストリーム上でやりとりされる\n", " - 0-9の10種類がありIDが振られている\n", " - クライアント側は奇数、サーバ側は偶数番号を割り当て、重複を防いでいる\n", " - ストリームはサーバ側でもクライアント側でも開始可能\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "| Type | フレームの種類 | 役割 |\n", "|:----:|:--------------:|:------------------------------------------------------:|\n", "| 0 | DATA | リクエスト/レスポンスのボディ部分に相当 |\n", "| 1 | HEADERS | リクエスト/レスポンスのヘッダ部分に相当 |\n", "| 2 | PRIORITY | ストリームの優先順位を指定(クライアントのみ送信可能) |\n", "| 3 | RST_STREAM | エラーなどの理由でストリームを終了するために用いる |\n", "| 4 | SETTING | 接続設定を変更する |\n", "| 5 | PUSH_PROMISE | サーバプッシュを予告します(サーバのみ送信可能) |\n", "| 6 | PING | 接続の生存状態を調べる |\n", "| 7 | GOAWAY | エラーなどの理由で接続を終了するために用いる |\n", "| 8 | WINDOW_UPDATE | ウインドウサイズを変更する |\n", "| 9 | CONTINUATION | サイズの大きなHEADERS/PUSH_PROMISEフレームの断片 |" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "notes" } }, "source": [ "- 「フレーム」というのはHTTP/2の通信の最小単位\n", " - それぞれにフレームヘッダが含まれる" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### リクエストの優先度制御" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### 一言で言うと...\n", "\n", "→ リソースに優先順位を付けることでUXが向上" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### リクエストの優先度制御\n", "\n", "- クライアントがサーバーに優先順位ツリーを送信することで、レスポンス優先度を指定できる\n", "- 重み付け\n", " - 割り当てるリソースの割合を比率でしている\n", " - 1~256の整数の重みを割り当てる\n", " - デフォルトは16\n", "- 依存関係\n", " - 各ストリームは、別のストリームに対して明示的な依存関係を指定できる\n", " - より依存されているものが優先的に送られる\n", "- 優先度を付けることでユーザ体感速度を大幅に向上させることができる\n", "- [わかりやすい参考記事](https://qiita.com/Jxck_/items/16a5a9e9983e9ea1129f)\n", "- [わかりやすい参考スライド](https://www.slideshare.net/kazuho/http-58452175)\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "- ![重み付け](https://developers.google.com/web/fundamentals/performance/http2/images/stream_prioritization01.svg?hl=ja)\n", " \n", " - 画像引用元: [HTTP/2 の概要  |  Web  |  Google Developers](https://developers.google.com/web/fundamentals/performance/http2/?hl=ja)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "notes" } }, "source": [ "- 先ほど紹介した2番のPRIORITYフレームを用いる\n", "- 偶数であることからもわかるように、クライアント側で指定する\n", "- サーバー側はクライアントから来たこの優先度は別に無視することもできる\n", "\n", "- 例えば、A,B,Cという画像かなにかがあって、これらに対して8,16,32のように重み付けをすると、\n", "- 1:2:3の割合でリソースが割り当てられることが期待される" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## HTTP/2の特徴\n", "\n", "- ヘッダの圧縮\n", "- リクエストの多重化\n", "- __リクエストの優先度制御__ ← マダココ\n", "- サーバープッシュ \n", "- バイナリプロトコル\n", "- フロー制御" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### サーバプッシュ\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### 一言で言うと...\n", "\n", "→ サーバーが次にくるレスポンスを先読みしてリクエストを返す" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### サーバープッシュ\n", "\n", "- サーバーがクライアントの発行するリクエストを予測してレスポンスを返す\n", "- 0RTTにすることができる\n", "- [詳細でわかりやすい解説記事](http://labs.gree.jp/blog/2014/12/11987/)\n", "\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "notes" } }, "source": [ "- 1RTT(ラウンドトリップディレイ・タイム)は1往復にかかる時間のこと\n", "- HTTP/2にしたところで1RTTかかっちゃうけど、どうにか0RTTにしたいよな的な発想\n", "- リソースの数が増えればそれで時間がかかる" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### 例 \"index.html\"\n", "```\n", "\n", "\n", "\n", " \n", " マジ卍\n", "\n", "\n", "

おはようございます!!!!!!!!

\n", " \"超おもしろい画像\"\n", "\n", "\n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### 従来\n", "\n", "1. index.htmlくれとリクエストを送る\n", "2. サーバーがindex.htmlを返す\n", "3. クライアントが上からindex.htmlをパース\n", "4. imgタグを見つけたら、再びomosiro.pngくれとリクエストを送る\n", "5. サーバーがomosiro.pngを返す\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### サーバプッシュ\n", "1. index.htmlくれとリクエストを送る\n", "2. サーバーがindex.htmlとomosiro.pngを返す\n", "3. クライアントはomosiro.pngをキャッシュにセット\n", "4. クライアントが上からindex.htmlをパース\n", "5. imgが必要なことを発見しキャッシュを見に行く\n", "6. キャッシュにあるのでリクエストせずに表示" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### バイナリベース" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### 一言で言うと...\n", "\n", "→ 機械語で通信" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### バイナリベース\n", "\n", "- テキストベースからバイナリベースへ\n", "- サーバがパースを簡単に行える\n", "- 転送データ量の低減\n", "- エラーや間違いを減らす\n", "- セキュリティ向上\n", " - HTTP Response Splitting Attack\n", " - レスポンス分割攻撃" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "notes" } }, "source": [ "- 0と1\n", "- 間違い\n", " - 空白、大文字小文字の区別、改行コードなど" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### フロー制御" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### 一言で言うと...\n", "\n", "→ 通信路の渋滞をなくす!" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### フロー制御\n", "\n", "- 巨大なリソースがストリームを専有して他のストリームがブロックしてしまうことを防ぐ\n", "- TCPでも実装されている\n", " - HTTP/2ではストリーム毎にフロー制御\n", "- 仕組みの概要\n", " - 1回で送れる容量の上限を決めてそれ以上のものが来たら止める\n", " - 必要になったら残りを送る\n", " - [わかりやすい記事](https://qiita.com/Jxck_/items/622162ad8bcb69fa043d)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "notes" } }, "source": [ "- 低レイヤでも頑張っているが、アプリケーション層でも頑張る!" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# 比較のデモページ\n", "\n", "- http://www.http2demo.io/\n", "- https://http2.akamai.com/demo\n", "- http://www.httpvshttps.com/\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# 調べてみた感想\n", "\n", "- HTTP/2新たに追加された機能がいっぱいあった\n", "- 一つ一つが勉強会の題材にできるくらい深めたら面白そうだった\n", "- もうちょい詳細にしてブログにまとめます" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# 参考文献\n", "\n", "これまでのスライド中に書いていない参考にした書籍やリンク先\n", "\n", "- [Real World HTTP]()\n", "- [HTTP/2 - Wikipedia](https://ja.wikipedia.org/wiki/HTTP/2)\n", "- [HTTP/2の特徴 HTTP/1.1との違いについて | REDBOX Labo](https://blog.redbox.ne.jp/http2-cdn.html)\n", "- [なぜ、我々はHTTP/2に対応する必要があるのか? | SEO Japan – アイオイクスによる海外最新SEO情報ブログ](http://www.seojapan.com/blog/everyone-moving-http2)\n", "- [HTTPとサーバ技術の最新動向](https://www.slideshare.net/kazuho/http-58452175)\n", "- [HTTP/2 の概要  |  Web  |  Google Developers](https://developers.google.com/web/fundamentals/performance/http2/?hl=ja)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# おまけ" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## 普及率\n", " \n", "- 日本では70%弱\n", "- [Mozillaのデータ](https://letsencrypt.org/stats/#percent-pageloads)\n", "- [Googleのデータ](https://transparencyreport.google.com/https/overview)\n", "- [広まった理由とか解説されているサイト](https://medium.com/anderswodenkender/%E6%97%A5%E6%9C%AC%E3%81%AEhttps%E5%B0%8E%E5%85%A5-%E6%99%AE%E5%8F%8A%E3%81%97%E3%81%A4%E3%81%A4%E3%82%82%E3%81%BE%E3%81%A0%E4%B8%8D%E5%8D%81%E5%88%86-380dd64d9603)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## 導入方法\n", "\n", "- クライアント側は対応してるブラウザ使うだけ\n", "- サーバー側は必要なモジュールを入れる\n", " - TLS1.2以上が必要なので証明書つくる\n", "- [導入する方法](http://dskst9.hatenablog.com/entry/2016/01/30/235019)" ] } ], "metadata": { "celltoolbar": "Slideshow", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.1" }, "toc": { "nav_menu": {}, "number_sections": false, "sideBar": true, "skip_h1_title": false, "toc_cell": false, "toc_position": { "height": "794px", "left": "0px", "right": "1466px", "top": "111px", "width": "212px" }, "toc_section_display": "block", "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }