본문

Tech
HTTP/2について - 第1編

작성일 2019.07.29

blog_38_main.webp

最近、多くのWebサービスがHTTP / 2で行われています。WhaTap MonitoringのSaaSサービスもAWSのALBを介してHTTP/2プロトコルでサービスされています。HTTP/2は従来のHTTP/1.xと比べてパフォーマンスが優れています。そのため、サービス中のWebサービスがHTTP/1.1で通信している場合は、HTTP/2に必要なオプションと機能を追加するだけで多くのパフォーマンスが向上します。それでは、HTTP/2の重要な内容を簡単に調べて、実際のTomcatでHTTP/2通信を適用してみましょう。

HTTP/1.x

HTTP/2(以下H2)とHTTP/1.x(以下H1)との最大の変化は速度向上です。H1の性能低下部分と非効率的なものを改善して誕生したのがH2だと考えると簡単です。H1で問題となる部分を見て、H2ではどのように解決したかを見てみましょう。

HTTP/1.1

HTTPはTCP接続ベースで動作するプロトコルです。信頼性を確保するために接続を確立および切断するためにハンドシェイクが行われます。さらに、HTTPは非接続プロトコルなので、一度接続で1回の要求と応答を行い、応答が終わると接続を切断してしまいます。接続を確立して切断するたびにハンドシェイクを行うため、非接続プロトコルではオーバーヘッドが発生します。特に、最近のWebサービスは、ハイパーテキストではなく、多くの静的データからなるハイパーメディアに発展しているため、オーバーヘッドが大きくなる可能性があります。そのため、HTTP/1.1では、Keep-alive機能が追加され、一度確立された接続を切断せずに継続的に維持することで、不要なハンドシェイクを減らしてパフォーマンスを向上させることができます。このようにWebページが以前のテキスト中心とは異なり、ますますメディアが追加され、状態(クッキー、セッションなど)を維持しようとする技術が求められるため、性能改善が必ず必要になり、そのために追加的な機能が追加されてH2まで 発展するようになったのです。

HTTP/1.1では、パフォーマンスを向上させるためにパイプライニングと呼ばれる技術が導入されました。1つのコネクションで一度に順次的な複数の要求を連続的に行い、その順序に応じて応答を受ける方法で遅延時間を短縮する方法です。順番にデータを要求して受け取る必要があるので、最初に受信した要求が終了しない場合は、その後の要求の処理がいくら早く終了しても、最初に来た要求が終了するまで待たなければなりません。これをHTTPのHOL(Head Of Line) Blocking問題といい、パイプライニングの大きな問題です。そのため、現代のブラウザはほとんどがパイプライン化を使用しないようにしました。そのため、H1で通信する際、クライアント(ブラウザ)が要求を並列にするために、6~8個(ブラウザごとに異なる)のコネクションを利用してデータを取り込む方法で性能を改善しています。

HTTP/1.1 パイプライニングHTTP/1.1 パイプライニング
Chrome開発者ツールで確認したHTTP/1.1のデータ要求応答過程で6つのコネクションIDが使用された。Chrome開発者ツールで確認したHTTP/1.1のデータ要求応答過程で6つのコネクションIDが使用された。

HTTP/2のバイナリフレームと多重化

H2の鍵は、バイナリフレーミングレイヤを使用してリクエストとレスポンスの多重化をサポートすることです。HTTPメッセージをバイナリ形式のフレームに分割し、送信後に受信側で再構築します。 要求と応答が同時に行われるため、1つの接続に複数の要求と応答が混在しています。フレーミング操作はサーバーとクライアント(ブラウザ)で行われるため、大きな変更を考慮する必要はありません。バイナリフレーミングと多重化を利用して複数の接続なしで並列処理もでき、パイプライニングと異なりHOL問題を解決したのです。

さらに、要求の優先順位を指定でき、ヘッダーを圧縮してヘッダーのオーバーヘッドを減らし、クライアントが明示的な要求をしなくても必要なリソースを事前にプッシュして応答時間を短縮するサーバープッシュ機能を追加しました。H2の発展プロセスと目標、詳細な技術的な内容は、Google開発者ページにあります。

バイナリフレーミングレイヤソース:Googleバイナリフレーミングレイヤソース:Google

用語の説明

  • ストリーム:構成された接続内で転送されるバイトの双方向フローであり、1つ以上のメッセージが転送されることがあります。
  • メッセージ: 論理要求または応答メッセージにマッピングされるフレームのシーケンス全体。
  • フレーム: HTTP / 2での通信の最小単位であり、各最小単位には1つのフレームヘッダが含まれています。 このフレームヘッダは、少なくともフレームが属するストリームを識別する。

さて、実際のTomcatを使ってH2の設定をし、簡単なWASを作り、HTTP/1.1とHTTP/2のページロード時間を比較してみましょう。

TomcatでH2を設定してH1と簡単に比較する

Tomcatは8.5以上のバージョンからH2をサポートしています。 ただし、8.5では、APR(Tomcat Native)をインストールしなければH2が機能しません。また、H2と通信するためにTLSを適用する必要があります。TLS 適用は H2 の標準ではありませんが、ほとんどのブラウザで TLS 設定ができていないと H2と通信ができないようになっています。

Tomcat 8.5バージョンでHTTPSとAPRを設定し、WhaTapのロゴを225個の画像に分割してそれを転送するWASを作成しました。そして、TomcatサーバーはローカルVMにインストールされているため、肉眼でもパフォーマンスの違いを見積もることができるように、強制的にネットワークスロットリングをかけてレイテンシを30msに設定し、ブラウザキャッシュ機能をオフにしました。 HTTP/2 用のTomcatでのTomcat Native のインストールと以下のコネクタ設定がすべてです。その後、ブラウザでH2をサポートするとH2と通信し、そうでない場合はH1と通信します。

Tomcat HTTP / 2設定コネクタ設定Tomcat HTTP / 2設定コネクタ設定
HTTPS/1.1 イメージロード時間HTTPS/1.1 イメージロード時間
HTTP/2 イメージの読み込み時間HTTP/2 イメージの読み込み時間

上の画像を見ると、H2が同じ条件で2倍に近い性能改善を示しています。このパフォーマンスの違いは、レイテンシの悪い環境でより明確になります。また、全体の転送データサイズも減るため、ネットワーク負荷も軽減されます。H2の設定のみを行うと、全体的なパフォーマンスを簡単に改善できます。

次のポストでは、ここで作成したTomcat WASを使用してパケットを収集し、ヘッダーフレームとデータフレームがどのようにやり取りされるかをもう少し詳しくご説明します。

WhaTap Monitoringを体験してみましょう。
難しかったモニタリングと分析が容易に実現できます。