ざっくりHTTP/2

この記事はSFC-RG Advent Calendar 2017の15日目です。

何か書かなければならないので、とりあえず、最近読んだreal world httpの中から、

HTTP/2とは結局なんなのかということを書いてみる。

Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術

Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術

本の途中でgolangでの実装が書いてあったが、コーディングやってない。読んだだけ。

HTTP/1.1からの主な変更点

基本的に、メソッド、ヘッダー、ステータスコード、ボディという4つの基本要素は変わらない。

HTTP/2の最大の目的は、通信の高速化である。

HTTP/2は、これまでとは完全に異なったプロトコルであり、後方互換性の問題が逆に起きにくくなっている。

これは、内部でのバージョンの切り替えではなく、TLS内に作られたプロトコル選択機能で、通信方式を大きく切り替えているためである。

HTTP/2になったことで、一番大きな変化は、テキストベースから、バイナリベースになったことである。

HTTP/1.1までは、一つのリクエストが、TCPのソケットを占有してしまうため、一つのサーバーに対して、2〜6本のTCP接続を行い並列化していた。

これがHTTP/2になると、TCP接続の内部に、ストリームという仮想のTCPソケットを用いて通信するようになる。

アプリケーション層

HTTP/1.1では、Keep-Aliveや、パイプライニングなど、下のレイヤーに影響を与えるような機能も実装されていた。

その内部には、

  1. メソッドとパス

  2. ヘッダー

  3. ボディ

  4. ステータスコード

という4つの要素が存在していた。

これらのうち、メソッドどパス、ステータスコードとそれに含まれるプロトコルバージョンは、擬似ヘッダーフィールド化されヘッダーの中に取り込まれた。

また、上に書いたように、HTTP/1.1は、テキストプロトコルのため、ヘッダーの終端を探すのに、一行一行チェックし、空行を見つけるまで1バイトずつ先読みしなければならなかった。

しかし、HTTP/2では、バイナリ化されているので、最初にフレームサイズが入っている。こうすることで、データをフレーム単位へ素早く分割できるようになる。

高速なウェブサイト

今までのHTTP/1.1では、CSSやJSは、なるべく同じファイルにまとめて、高速化される、というテクニックがあった。

これは、リクエストの回数を減らすことが目的である。

しかし、HTTP/2になったことで、このテクニックを使うことで得られる効果は、薄れるようになった。

まとめ

ストリームという仕組みを使って、バイナリデータをいっぱい送れるようになった。

ヘッダーが圧縮できるようになった。

結果、高速になった。