waste of time

主にPHP

HTTP/2の復習メモ

HTTP/2対応を行う機会が来そうな気がしないでもない感じがしてきたので、いろいろおさらいしてみる。

HTTP/1.1の特徴

  • 1つのコネクション上では、1リクエストが完了するまで、新しいリクエストを送ることができない
    • HTTP/1.1からはHTTPパイプラインがサポートされ、1コネクション上でリクエストの応答を待たずに新しいリクエストを送信することができるようになった
      • HTTPパイプラインの問題点
        • リクエストとレスポンスの順序は同期していなければならず、HOL(Head of Line)ブロッキング(先頭のレスポンスが遅いとその後のレスポンスも待ち状態になる)が生じ得る
        • そもそもモダンブラウザが対応していない・デフォルトで設定がオフになっている(実装が困難であったり、HOLブロッキングを回避するため)
        • よってHTTPパイプラインは広く使われていない
  • 効率化のため、多くのブラウザは、1ドメインへの接続を同時に複数行う(コネクションの多重化)
    • ブラウザは6リクエストを同時に行うために、同時に6コネクション使っている
    • 同時接続はサーバ・ネットワークへの負荷に直結する

HTTP/2の特徴

  • 1つのコネクション上で、複数のリクエストを非同期で並列化出来る
  • ヘッダを圧縮して送信するのに加え、前回からの差分のみ送信する
  • メッセージはテキストの代わりにバイナリでやり取りされる
  • 主要ブラウザは対応済み ただしHTTP/2 over TLSのみなので全ページSSL化必須
  • Apache2.4.17, nginx1.9.5対応済み
  • 開発経緯としては、GoogleのSPDYプロジェクトから発展

非同期並列接続による効率化に加え、ヘッダ圧縮やバイナリ化でデータサイズが小さくなるため、HTTP/2化するだけで基本的には恩恵を受けられそう。 テキストでなくバイナリでのやり取りになるので、多少デバッグしづらくなったりなどあるのだろうか…?

良いところばかりのように思えるが、弱点もある。 非同期並列接続の実現によりHTTPレベルのHOLブロッキングは発生しなくなるが、TCPレベルのHOLブロッキングが問題になる場合が出てくるようだ。 そもそもHOLブロッキングとは、TCPとHTTPそれぞれのプロトコルで発生しうるものらしい。

  • HTTPにおけるHOLブロッキング
    • HTTPパイプラインにおいて、コネクション上のある遅いHTTPリクエストにより後続のHTTPリクエストがブロックされる状態
  • TCPにおけるHOLブロッキング
    • IPパケットがロストして再送される際に、後続のIPパケットがブロックされる状態

HTTP/2化したからといって必ずしも全てのケースで高速化するかというとそうでもないようだ。 例えばサイズの大きい画像が大量にあるページの場合、HTTP HOLブロッキングよりもTCP HOLブロッキングのほうが問題になる可能性がある。HTTP1.1であればTCPのHOLブロッキングが生じても複数コネクションで回避(?)できていたが、HTTP/2ではコネクションは1つのみなのでTCPのHOLブロッキングは回避できない。 改善策としてmTCPやらQUICやら新しい取り組みがあるらしいがまだ普及には至っていない。 ということでHTTP/2で高速化するかどうかは実際のところは環境に依るし検証してみないと分からないというオチ。

参考