Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Webを早くする技術(HTTP)
Search
Haru(utsushiiro)
July 31, 2017
Programming
1
520
Webを早くする技術(HTTP)
Haru(utsushiiro)
July 31, 2017
Tweet
Share
More Decks by Haru(utsushiiro)
See All by Haru(utsushiiro)
メールの仕組み
utsushiiro
4
830
TCPその他の機能と性能 + TCP Fast Open + TLS False Start
utsushiiro
1
660
Dynamic Routing Protocols
utsushiiro
0
92
TCP
utsushiiro
0
83
Other Decks in Programming
See All in Programming
testcontainers のススメ
sgash708
1
120
テスト自動化失敗から再挑戦しチームにオーナーシップを委譲した話/STAC2024 macho
ma_cho29
1
1.3k
Scalaから始めるOpenFeature入門 / Scalaわいわい勉強会 #4
arthur1
1
330
ブラウザ単体でmp4書き出すまで - muddy-web - 2024-12
yue4u
3
470
103 Early Hints
sugi_0000
1
230
テストケースの名前はどうつけるべきか?
orgachem
PRO
0
130
CSC305 Lecture 26
javiergs
PRO
0
140
Итераторы в Go 1.23: зачем они нужны, как использовать, и насколько они быстрые?
lamodatech
0
760
暇に任せてProxmoxコンソール 作ってみました
karugamo
2
720
Jakarta EE meets AI
ivargrimstad
0
240
採用事例の少ないSvelteを選んだ理由と それを正解にするためにやっていること
oekazuma
2
1k
複雑な仕様に立ち向かうアーキテクチャ
myohei
0
170
Featured
See All Featured
Code Review Best Practice
trishagee
65
17k
We Have a Design System, Now What?
morganepeng
51
7.3k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
59k
Agile that works and the tools we love
rasmusluckow
328
21k
Bash Introduction
62gerente
608
210k
Building Your Own Lightsaber
phodgson
103
6.1k
It's Worth the Effort
3n
183
28k
Being A Developer After 40
akosma
87
590k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
6.9k
Speed Design
sergeychernyshev
25
670
A better future with KSS
kneath
238
17k
Imperfection Machines: The Place of Print at Facebook
scottboms
266
13k
Transcript
Webを速くする技術(HTTP編) HTTP/1.1→ HTTP/2 → QUIC @utushiiro
▷ Table of contents ◦ HTTPとは ◦ HTTP 1.1 ▪
Keep-Alive ▪ Pipelining ◦ プロトコル以外の部分での高速化 ◦ SPDY ◦ HTTP 2 ◦ QUIC
Hyper Text Transfer Protocol リソース(ファイル)の送受信に用いられる 通信プロトコル トランスポート層のプロトコルとしてはTCPを利用 主に Webブラウザ ⇔
Webサーバ GET index.html 1.1 ... 1.1 200 OK ...
▷ 1991年 HTTP/0.9 ▷ 1996年 HTTP/1.0 RFC 1945 ▷ 1999年
HTTP/1.1 RFC 2068 ▷ 2015年 HTTP/2 RFC 7045 HTTPの変遷
1つのリソースの取得毎に コネクションを確立する オーバーヘッド大きい HTTP/1.0までの問題点 HTTP Request HTTP Response コネクション確立処理 コネクション切断処理
HTTP Request HTTP Response
Keep-Alive (HTTP/1.1) リソースの取得毎にコネクションを確立する → オーバーヘッド大きい 複数のリソース取得のためにコネクションを 維持しておく仕組みとしてKeep-Aliveが実装 HTTP HeaderのConnectionヘッダを利用する 基本的に使われている機能
Keep-Alive (HTTP/1.1) HTTP Request HTTP Response HTTP Request HTTP Response
一連のリクエストの 最初と最後だけ
HTTP/1.1までの制約 1つのリクエストが完了(レスポンスを処理) するまで 原則次のリクエストを送れない つまり, 先頭が詰まると後続が止まってしまう これは HTTPのHead of Line
Blockingと呼ばれる 以後 Head of Line Blocking → HoL Blocking
パケットロス HTTP/1.1までの制約 HTTP Request 1 HTTP Response 1 HTTP Request
2 やっと2個目を送れる 遅延
Pipelining (HTTP/1.1) 1つのリクエストが完了(レスポンスを処理) するまで 原則次のリクエストを送れない レスポンスを待たずにリクエストを送信する 仕組みとしてPipeliningが実装 ※これはリクエストを一つのコネクションで 複数送信することを想定しているため Keep-Aliveが必要になる
Pipelining (HTTP/1.1) HTTP Request 1 HTTP Response 1 HTTP Request
2 HTTP Request 3 HTTP Response 2 HTTP Response 3
Pipelining (HTTP/1.1) ただし, クライアントからのリクエストの順序と サーバからのレスポンスの順序は 同期している必要がある なので, 結局先頭が詰まると後続も詰まる 大抵のブラウザでは使われていない機能
プロトコル以外の部分での高速化 ▷ CSSスプライト ▷ 画像のインライン化 ▷ Domain Sharding (後述) などなど
上記の手法のように プロトコル以外の部分で高速化を行っていた
Domain Sharding ブラウザは先述したHead of Line Blocking等 の影響を 小さくするために, 1ドメインに対して同時に複数のコネク ションを貼っている
Domain Shardingはリソースを複数のドメインに分散させ て更に同時接続数を増やす方法 ※ 画像を別ドメインにするサイトが多いが 理由としてはこれ↑とセキュリティ向上
Webコンテンツのリッチ化 1999年にHTTP1.1仕様化されて10年 Webではコンテンツの容量が劇的に増加 Contents Delivery Network (CDN)の導入や 通信環境の改善はあるのものの (利用者が増えたこともあり)表示速度等が問題に Webの表示を高速化するにはどうすれば良いか?
Webコンテンツのリッチ化 ネットワークの回線帯域を増加させても 一定値を超えるとあまり速くならない コンテンツのデータをやり取りする際の サーバ・ホスト間やり取りの多さ(= RTT ✕ 回数)が 大きな影響を与えている 通信環境を改善するよりも
プロトコルレベルでの改善が必要に
SPDY プロトコルレベルの改善としてGoogleが SPDY(スピーディー)を提唱 TLSの上にセッション層を追加する(置き換える) TLSの拡張仕様 Next Protocol Negotiation(※)を 利用するためHTTPSが必要 ※現在(HTTP2.0)では
Application Layer Protocol Negotiation(ALPN) 詳細は省きます
HTTP/2 SPDYをベースにHTTP/2が策定(RFC 7540) 1. 優先度付全二重多重化通信 2. プロトコルのバイナリベース化 3. HTTPヘッダーの圧縮 4.
フロー制御 1, 2, 3については後述. 4では主にHTTPのレイヤで, TCPのフロー制御の様なこ とをやるための枠組み(window size 制御)を仕様化して いる.
優先度付全二重多重化通信 (HTTP/2) まず 多重化 について, 1つのコネクションの上にストリーム(※)を 作って通信を行う このストリームは複数並列に扱えるため 前述したHead of
Line Blocking問題を解消する ※従来のRequest/Responseで行われる 一連のやり取りを行う仮想的な通信路
優先度付全二重多重化通信 (HTTP/2) それぞれ独立・並列 ストリーム 確立したコネクション
コネクションを使いまわすメリット Keep-alive や HTTP/2 のストリームは 一つのコネクション使いまわす 3 way handshake のオーバヘッドだけでなく
スロースタート等によるwindow sizeの調整に かかる時間のオーバヘッドも減らせる. また, 複数のコネクションを立てるのに比べて 効率的な輻輳制御が行われる(※). ※ 従来の複数では輻輳制御がそれぞれ独立して 行われるため, 帯域を効率的に使うのが難しい
優先度付全二重多重化通信 (HTTP/2) 次に 優先度 について, レンダリングする際にコンテンツの優先度を定めることに より, より効率的な配信を行う 従来はコードの配置場所を調整したりして ロードの順序を操作していた(
jsの位置とか) ※ただし, あくまで指標程度であり 必ずその順序になるとは限らない
優先度付全二重多重化通信 (HTTP/2) 次に 多重化 について, クライアント/サーバのどちらからも(※)ストリームを確立で き, いわゆるサーバプッシュができる ※従来はクライアントからのリクエストでないと セッションを開始できなかった
後に必要になるデータを予めキャッシュさせておく などの使用法がある
プロトコルのバイナリベース化 HTTP/1.1まではHTTPはテキストベース テキストベースだと ▷ 容量が大きい ▷ パースが煩雑 フレームと呼ばれるバイナリ形式のフォーマットを 採用して, 従来のRequest/Response,
Header等は すべてのこのフレームにマッピングされる
HTTPヘッダの圧縮 HTTP/1.1の頃は高速化の一つの手法として コンテンツデータの圧縮があった HTTP/2.0では, HTTPヘッダ部分を圧縮できる & 一度送信したヘッダは基本的に再度送信しなくて済む ようになっている(差分のみ送信) 現在ではHTTPヘッダで付加する情報が多いため これによる恩恵は大きい
HTTPヘッダの圧縮 SPDYの頃はデータと同様にGzip等で圧縮していたが CRIMEと呼ばれる脆弱性が発見された これはTLSで暗号化された通信上でも 圧縮されたヘッダデータを解読する手法(参考) そこでHTTP/2ではよりセキュアな圧縮方式としてHPACK が作られた(RFC 7541) ただし, 完全にCRIMEを防げるわけではない
TCPのHead of Line Blocking HTTP/2ではHTTPのHoL Blockingを防げる しかし, TCPのHoL Blockingは防げない ▷
TCPのHoL Blockingとは TCPでは先頭のパケットがロスすると 後続のパケットを処理することができない また, HTTP/2は1本のコネクション上で多重化する分 複数使っていた頃よりこれの影響が大きい恐れがある
QUIC 先述したTCP HoL Blockingの様な トランスポート層のプロトコルレベル(TCP)の 問題等を解決し, より効率的な通信を行うために GoogleのチームがUDPベースの新たなWeb向けのプ ロトコルを作成 Quick
UDP Internet Connections (QUIC)
なぜUDPベース? 長期的な目標はTCPやTLSの改善 しかし, TCP/TLSの改良(提案, 実装, 検証 … etc)には 時間がかかる UDPで理論を実践した後に,
有効な機能をTCP/TLSの 後続バージョンにフィードバックする (もちろん)UDPを用いるので先述した TCPのHoL Blockingは起きない(ようになってる)
QUICでやろうとしていること ▷ TCPやTLSの処理の効率化 ◦ 接続の確立時に必要なRTTを減らす (TFOやTLS False Startと同じ考え) ▷ パケット損失の影響を低減
◦ パケットレベルの前方誤り訂正 ◦ 暗号化のブロックやパケットの境界を整理 ▷ 再接続(接続の維持)の簡易化 ◦ 後述
再接続(接続の維持)の簡易化 モバイル端末ではWiFiとLTE(3G)を切り替えが起きえる が, この際に安定した接続を維持するのが難しい QUICでは接続を独自の識別子 Connection UUIDを 使用して, 回線の切り替えの際にも維持することで 以前の接続を引き継ぐ(再接続処理を簡易化)
TCPだとIP & portの4つ組で識別するので どれか変わるとが接続が切れる ( IP & portがそのまま識別子なので 同じようなことを同じレイヤでやることは難しい)
以上の話は HTTP/1.1 → QUICのざっくりとした流れ あくまで理論的(理想的?)な上辺のみを 扱ったので実際にはもっと泥臭い話が色々 実際の実践的な話は大規模インフラで 運用してる人のブログ・スライド等を読もう あとRFC
Credit ▷ Presentation template by SlidesCarnival