「マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
目次 †
概要 †
gRPCを調べようと思っていたら、HTTP/2なるキーワードが。
「そういや話題になっていたなぁ。」などと思い少々調査してみました。
HTTP/2とは †
経緯 †
- 米GoogleによるWeb高速化の「SPDY」プロトコルが生み出された。
- 有名サイトも次々と「SPDY」を取り入れるようになった。
- 標準化団体IETFによって標準化が進められ、RFC(RFC7540, HTTP/2)化した。
目的 †
HTTPの高速化
方法 †
ストリームという仕組みを使用する。
プロトコル †
- 既存のHTTPと互換性を保ちながらセッション層を効率化する。
- そのため、HTTPの表面上の機能はそのままに、内部動作だけを置き換える。
今後 †
- まだ、十分な実績がないので、検証中のプロトコル。
- HTTP/1.1に置き換わるのか?
- 一部の仕様だけが生き残るのか?
- HTTP/2はTCP/IP上で動作するため、品質の低い回線上で実行した場合、
パケット遅延、パケットロスなどで全体遅延になる問題がある。
- このため、米Googleは「QUIC」というUDP上でHTTPを処理する新しいプロトコルを開発中である。
- 「QUIC」も「SPDY」と同様に、IETFを通じた標準化を目指している。
HTTPの高速化 †
通信・接続の多重化 †
- HTTPでは、1つのリクエストが完了するまで、次のリクエストを送ることができない。
- 現在、多くのブラウザは1ドメインへの接続を同時に複数行い、通信を多重化している。
- ただし、HTTP/1.1の仕様としては2つまでとされている。
HTTPパイプラインとHoL(Head of Line)ブロッキング †
- HTTPパイプライン
- HTTP/1.1から、前回リクエストの完了を待たずに次のリクエストを送信可能
- しかし、実装の困難さから、HTTPパイプラインを正しく実装したサーバが少ない
- 故に、現在ほとんどのブラウザはHTTPパイプライン機能を全く実装していないか、デフォルトでオフ。
- HoL(Head of Line)ブロッキング
- HTTPパイプラインには、「サーバはリクエストの順番通りにレスポンスを返さなければならない」という制限がある。
- これは、「先頭のリクエストの処理に時間がかかる場合、後続のレスポンスは全てブロックされる」という問題を起こす。
リソース読み込みを速くする様々な工夫 †
- リソースの結合
- CSSやJSファイルを1つに結合するテクニック
- ASP.NETではBundle機能が提供されている。
- ドメインシャーディング
- 多重化には、前述の制限がある。
- この制限を搔い潜るためリソースファイルの取得先ドメインを分割する。
- ベターユース的には、
- 著名なライブラリの取得はCDNを使用すると良い。
- なお、CDNダウン時の対応として、CDNフォールバックというテクニックがある。
HTTP/2のストリーム †
- 1つのTCP/IPコネクション上でリクエスト・レスポンスを並列化する。
- ストリームの多重化によりHoLブロッキングの問題は解決する。
フレーム †
- 並列化のためフレーム
- 各ストリームにおけるメッセージのやり取りはフレームという単位で行う。
- フレームはバイナリで定義され、各フレームは9オクテットのヘッダと、可変長のペイロードで構成される。
- PRIORITYフレーム
- クライアントがPRIORITYフレームを用いてストリーム間に優先順位を付ける
- 優先順位付けの方法には、「重み付け」と「依存関係」の2つがある。
ストリームのID †
- ストリームはクライアント、サーバのどちらからでも開始できる。
- 競合回避のため、
- クライアント側から開始したストリームには奇数のIDを割り当てる。
- サーバ側から開始したストリームには偶数のIDを割り当てる。
ウインドウ制御 †
- TCP/IPでも実装されているようなウインドウ制御を実装している。
- HTTP/2で実装する理由は、
- TCP/IPコネクションを並列化しているため。
- 並列化した中の個別のストリームの制御を行う。
- 例:動画のストリーミング中に、そのストリームのみ停止する。
ヘッダ圧縮 †
従来、HTTPのコンテンツボディのみをgzip圧縮していたが、HTTP/2では、
- ストリーム内のHTTPヘッダも圧縮する。
- 圧縮には、gzipではなく、HPACKを使用する。
CRIMEというgzip圧縮の特性に着目して、
SSL暗号を無効化する攻撃手法を回避するため。
サーバプッシュ †
サーバ側からクライアントにデータをプッシュできる。
- 具体的に言えば、リクエストされたページに必要なリソースを予めクライアントに送信しておくための仕様と言える。
- 使用例としては、HTMLに関連付けられているCSSや画像などのリソースを、クライアントのリクエストを待たずにサーバーからプッシュ送信できる。
使い方 †
- 内部動作だけを置き換えるので、コンテンツ側は何もしなくてイイ。
- サーバープッシュだけは、コンテンツ側に実装の変更が必要になる。
サーバープッシュ †
- 前述のサーバプッシュを使用する場合、コンテンツ側に実装の変更が必要になる。
- ASP.NET MVCでサーバープッシュを使用する場合、
以下に、URLヘルパに拡張メソッドとして実装した例がある。
(故にUrl.PushContent?とか、UrlHelper?.PushContent?で検索しても出てこない)。
参考 †
サポート状況 †
IISというか、http.sys(HTTP カーネル モード ドライバ)で、サポートされている模様。
参考 †
.NET †
- .NET 2015(.NET Framework 4.6および.NET Core)から、サポートされている模様。
- 従って、当該バージョン以降のASP.NET & HTTPClientで使用可能。
参考 †
その他 †
サーバー †
IIS, Apache, nginx等の主要なサーバーで、サポートされている模様。
クライアント †
- 主要なブラウザで、HTTP/2 over TLSでサポートされている模様。
- IE11を含むが、Win10上のIE11に限定される模様。
参考 †
参考 †
Tags: :通信技術, :IIS, :.NET開発, :.NET Core, :ASP.NET, :ASP.NET MVC