HTTP/2速習会に行ってきた

HTTP/2速習会

Wantedlyにて行われたHTTP/2の速習会に行ってきました。

HTTP1.1の問題

解決策

  • ブラウザから6並列リクエスト
    • TCPコネクションを増やす
    • 7個以降はblock
    • socketの浪費につながる
  • HTTPパイプライン
    • レスポンスを待たずにrequestを送る
    • ただし、先に送ったrequestに対してresponseを返さないといけない
  • HTTPrequest数を減らすためのハック
    • ドメインシャーディング
      • ホスト数を増やす
    • CSSをconcatして一つにする
    • 小さな画像を結合して一つの大きな画像にする。cssで一部表示

HTTP/2

多重化

  • 一つのTCPコネクションで、複数のrequest/responseができるようになった
  • ストリームを使って実現している
    • 1request 1responseに対して1ストリーム
  • データ送信はバイナリのフレーム単位
    • フレームがごちゃごちゃで送られる
    • どのフレームがどのストリームに属しているかを管理している
  • フレームをデコードすると1.1と変わらない

ヘッダ圧縮

  • HPACKで圧縮
    • Huffman符号化
    • 頻出ヘッダーは共有
    • 送信ずみデータを再利用
    • RFC7541参照

優先度制御

  • 多重化されたresponseを優先度に応じて返す
    • 重み付け(他の何倍の割合で送信)を依存関係
    • HTML > CSS, JS > 画像
    • ブラウザが指定する

サーバープッシュ

  • 複数のレスポンスを返せる
    • CSS,JS等どうせ必要なものはrequest来る前に先に送ってしまう

H2Oを動かしてみる

$ git clone https://github.com/south37/http2-sokusyukai
$ cd http2-sokusyukai
$ docker run -p "8080:80" -ti south37/h2o-http2-demo-server

そのた詳しくは‥ https://github.com/south37/http2-sokusyukai

多重化で優先度を明示的に付ける場合は http2-reprioritize-blocking-assets: ON という設定を行う https://github.com/south37/http2-sokusyukai/blob/master/2_multiplexing/h2o/h2o.conf

サーバープッシュ ref=preloadというAttributeがimgタグにあれば勝手にやってくれる response header に link:</images/photo180.jpg>; rel=preloadが出て来る アプリケーションを書く人がいじるところ

http2-casper: ON クライアントがすでにキャッシュしているものを送らない キャッシュ情報はCookieで管理している

まとめ

  • HTTPのセマンティックはかえずに多重化などを解決
  • H2Oや最新のnginxであれば対応している
  • インストールが簡単 https://h2o.examp1e.net/install.html brewとかyumとかdocker imageとか

質問

  • 実際に導入してみてベンチマーク
    • そんなにかわらない
      • 画像関連はCDNとかつかってるから
      • 4つくらいのrequestしかない
    • NewRelicやh2load(http2に対応したapache bench)
    • https://hub.docker.com/r/svagi/h2load/
    • ヘッダー圧縮の影響でちょっと早い
    • APIをたくさん送りまくって、一つ一つをシンプルにするというのが効果高い
      • SPAだと効果あるように実装できるかもしれない
  • NginxでiOS SafariからHTTP2でPOSTしようとするとエラー
    • 最新版だとnginxのバグが修正されている