Yapc2015 HTTP/2 時代のウェブサイト設計

HTTP/2時代のウェブサイト設計 #http2webhttptls 
http://www.slideshare.net/kazuho/http2-51888328

[HTTP/2 時代のウェブサイト設計]
Kauho @ DeNA Co

#　ウェブサイトと応答速度
* 200ms -.0.5%
* 500ms -1.0%
* 1000ms -1.9%
* 2000ms -4.4%


* band haba 1983->2013
　 年率50%増えている
* ページロード時間はバンド幅に比例しない(5Mbps(実行1.6Mbps) くらいでさちる)

* Latencyy (RTT) を短くすると比例して短くなる

# HTTPS1.1
レスポンスを待つ
1RTT（ラウンドトリップタイム） あたり パイプライン6リクエストがマックス
ただ、パイプラインは使われていない
　- 切断時に、レスポンス未受診のリクエストを再送信していいかわからない
  - 先の処理に時間が後続がつまる

Latencyは光の速さなので変わらない　アメリカ往復で80 milli
携帯回線はLatency LTE- 50msec

#HTTP/2
RFC 7540
Google QUIC プロトコルを参考に

## バイナリプロトコル
* 脆弱性を防ぐ
  - HTTP/1.1 解釈の差をつく攻撃

* 転送単位が小さい

## フレーム
さまざまなフレームタイプ
Data: Type 0x0, used to transmit regular data in a connection.
Headers: Type 0x1, used to open a stream and additionally carries a header block fragment.
Priority: Type 0x2, specifies the sender-advised priority of a stream
RST_STREAM: Type 0x3, allows for immediate termination of a stream.  RST_STREAM is sent to request cancellation of a stream or to indicate that an error condition has occurred
Settings: Type 0x4, used to transmit configuration parameters that affect how endpoints communicate, such as preferences and constraints on peer behavior.  The settings frame is also used to acknowledge the receipt of those parameters.
PUSH_PROMISE: Type 0x5, used to notify the peer endpoint in advance of streams the sender intends to initiate.
PING: Type 0x6, used as a mechanism for measuring a minimal round-trip time from the sender, as well as determining whether an idle connection is still functional.
GOAWAY: 0x7, used to initiate shutdown of a connection or to signal serious error conditions.  GOAWAY allows an endpoint to gracefully stop accepting new streams while still finishing processing of previously established streams.
WINDOW_UPDATE: type=0x8, used to implement flow control.
Continuation: type=0x9, used to continue a sequence of header block fragments.  Any number of CONTINUATION frames can be sent, as long as the preceding frame is on the same stream and is a HEADERS, PUSH_PROMISE, or CONTINUATION frame without the END_HEADERS flag set.


## h2i コマンドでためすことが可能
http1.1 で手打ちするとhttp2でおくってくる


## 多重度
同時に100以上のリクエストを送信
任意のタイミングで送信OK

## ヘッダ圧縮
* HTTP1.1 では 最低300byte
* 100個レスポンスを受け取るならそれだけで30KB
HPACK(RFC7541)として規定
所見の文字列は静的Hafman
2度目以降はoffset

### 例
* / 最初のリクエスト 291 -> 147byte
* /banner.jpg  300->62 (直前の情報を使いまわす)
* /icon.png  298->17 (前回ほとんど同じ)

## 優先度制御
* ２種類の制御手法の組み合わせ
　- 重みづけ(weight)
  - 依存関係(dependency)

* クライアントが優先度を指定する
* Browserが優先度を決定
* Firefoxは依存関係、優先度両方つかう
* Chromeは優先度なし


HTML < CSS,JS(Head) Weight高い
HTML > image

Unblocked(Weight:101)
GoogleAnalyticsなどの(JS Body)
DomContentLoaded


* H2Oのrepriorize-blocking-assetsを有効にするとServerでよい順番で返してくれる

H2O
nghttp2
ここまでが使い物になる
--
appache
nginx
OpenLiteSpeed


## サーバープッシュ
* HTTP/2 はRTTを隠ぺいする技術
* 1 RTT-> 0 RTT
* 予測して先にクライアントに返す！

### 問題
* RFC通り実装してあってもあまり役に立たない

###
* プッシュするリソースは常に最優先
* 1.5 からはmime-typeを見て優先度制御

### Browser キャッシュしてるものは送りたくない
H2O  BrowserCach CSS, JS を fingerprinting
coolie 100byteほどで　状態を把握


## Http/2 でオワコン
* アセットの結合
*　expiresの利用（style.css?date=20150xxx）
 - HTTP/2 なら　304 レスポンス使い放題
 
迷ったら転送データ量を基準に考えればよい

* ドメインシャーディング
　- アセットを別ホストに置くことで同時接続を6歩に状にするハック

* CDNを使っている場合はWeb アプリからの応答もCDN経由で流すようにしましょう。

# HTTP/2, HTTPS
* サーバー証明書
* LetsEncrypt 無料で証明書もらえるようになります

# TLS
* Ciphersuites
使ってよい暗号化手法の一覧

## Forward Secrecy
* 一個解読されてもすべてがだめにならないようにする
* 全ての暗号

## Session Cache
* 公開鍵暗号の負荷
* 2RTT

* Session resumption
 サーバー、クライアント　TLS共通かぎ
* Session ticket
 電子証明書でクライアントにおぼえさせる

多くのウェブサーバーはsession ticketを優先する
session ticketを暗号化する鍵はサーバー動作中は変わらない

一般的なサーバーではsession ticket を無効化しないとPFSではない
自分で鍵をロールオーバーしないといけない

* H2Oならセッションキャッシュ
- クラスタのresumtionに対応
- session ticketの秘密鍵の自動更新機能を実装

H2O は nginx も追いかけてくる

## HTTPS
Q. Rest API client側の実装はどうする？
A. Client library は　１個しかない libcurl のみ

Q.ブラウザによってできること、できないことがある
 fire foxでの　first pain timeはどうやって計測した？
A. BrowserのNetwork timingu chart  (最後のjsを取得したタイミング)

Q. HTTP2 いつごろ普及する？
A. chrome, firefox , edge 対応済み　safari 秋
　nginxも 秋　に出てくる
　現状1割->年末には3割程度まで　http2化が進むでしょう。