
このブログ記事は、9月にサンフランシスコで開催されたnginx.conf 2015で、Valentin V. Bartenevが行ったプレゼンテーションを基に編集したものです。
目次
| 0:20 | プロトコルの概要 |
| 1:40 | HTTP/2の主な機能 |
| 3:08 | HTTP/2の内部 – バイナリ |
| 4:26 | HTTP/2の内部 – 多重化 |
| 7:09 | HTTP/2の主な機能 – ヘッダー圧縮 |
| 8:40 | HTTP/2の主な機能 – 優先順位付け |
| 10:06 | HTTP/2の歴史 |
| 10:16 | テストページ |
| 10:52 | テスト環境 |
| 11:02 | DOMの読み込み |
| 11:48 | 初回描画 |
| 12:45 | 設定 |
| 14:20 | Q&A |
数日前、NGINXのHTTP/2モジュールをリリースしました。この講演では、この新しいモジュールの概要を簡単にご紹介します。
0:20 プロトコルの概要

まず、この新しいプロトコルにまつわる誤解をいくつか解いておきます。
多くの人は、HTTP/2をHTTP/1の新しく優れた後継プロトコルだと考えています。しかし、私はそうは考えていません。その理由を説明します。実際のところ、HTTP/2はHTTP/1の別のトランスポート層にすぎません。とはいえ、これは悪いことではありません。同じヘッダーを使用できるため、アプリケーションを変更せずにHTTP/2を利用できるからです。NGINXでHTTP/2を有効にするだけで、プロトコルに関する処理はすべてNGINXが適切に行います。
しかし、HTTP/2は万能ではありません。長所もあれば短所もあります。適切に機能するユースケースがある一方で、うまく機能しないシナリオもあります。
1:40 HTTP/2の主な機能

HTTP/2はSPDYをベースとしており、非常によく似たプロトコルであるため、SPDYの新しいバージョンと考えることができます。SPDYは、Webコンテンツの配信を高速化するためにGoogleが数年前に開発したプロトコルです。
NGINXはすでに2年前からSPDYをサポートしているため、SPDYモジュールを使用してHTTP/2の利点を確認できます。HTTP/2はSPDY 3.1を洗練させたものにすぎないという見方もあります。
SPDYをご存じない方のために、いくつかの要点を説明します。細部には多少の違いがあるものの、基本的には同じプロトコルであるため、これらの要点はHTTP/2にも当てはまります。
最初の重要なポイントは、プロトコル自体がバイナリ形式であることです。バイナリプロトコルはコーディングしやすく、適切に設計されたものにはパフォーマンス上の利点もあるため、私は好んでいます。ただし、このアプローチに欠点があることも理解しています。
3:08 HTTP/2の内部 – バイナリ

こちらはHTTP/2リクエストです。なかなか格好よく、見てのとおりデバッグもとても簡単です。……というのは冗談で、実際にはデバッグが困難です。これはバイナリプロトコルの欠点の1つです。
リクエストのデコードにツールが必要になる場合があります。あるいは……ツールが正常に動作しなかったり、ビットに隠された詳細がすべて表示されなかったりするため、バイナリを手動でデバッグしなければならないこともあります。
幸い、ほとんどの場合はNGINXでHTTP/2を有効にするだけで、そのバイナリ形式を意識する必要はありません。また幸いなことに、ほとんどのリクエストはマシンによって処理されます。バイナリプロトコルの読み取りは、人間よりもマシンのほうがはるかに得意です。
4:26 HTTP/2の内部 – 多重化

HTTP/2の次の重要なポイントは、多重化です。複数の接続を介してレスポンスとリクエストを個別のデータストリームとして送受信するのではなく、HTTP/2では、これらを1つのバイトストリーム、つまり1つのデータストリーム上で多重化します。異なるリクエストやレスポンスのデータを分割し、各データ片に固有の識別子とサイズフィールドを付与することで、エンドポイントは各データがどのリクエストに属するかを判別できます。
ここでの欠点は、データの各チャンクに固有の識別情報とフィールドがあるため、実際のデータに加えてメタデータも転送されることです。そのため、一定のオーバーヘッドが発生します。したがって、動画を視聴する場合など、データストリームが1つしかない場合、追加のオーバーヘッドが生じるだけなので、HTTP/2は適したプロトコルではありません。
多重化にはどのようなメリットがあるのでしょうか。最大のメリットは、単一の接続のみを使用することで、新しいリクエストを作成する際にHTTP/1.xでは必要となるハンドシェイクの時間をすべて省けることです。
このような遅延は、TLSを使用する場合に特に大きな問題となります。そのため、現在ではほとんどのクライアントがTLS経由でのみHTTP/2をサポートしています。私の知る限り、暗号化されていないTCP経由でHTTP/2をサポートする計画はありません。そうしても大きなメリットがないためです。TCPハンドシェイクはTLSハンドシェイクほど負荷が高くないため、複数の接続を避けても、ここではそれほど時間を短縮できません。
7:09 HTTP/2の主な機能 – ヘッダー圧縮

HTTP/2の次の重要なポイントは、ヘッダー圧縮です。Cookieが非常に大きい場合は、リクエストまたはレスポンスごとに数百バイトを削減できますが、一般的には、ヘッダー圧縮のメリットを得られるケースはそれほど多くありません。個々のリクエスト単位で考えても、最終的にはネットワークのパケット層で処理されるためです。100バイトを送信しても150バイトを送信しても、結局は1つのパケットに収まるので、大きな違いはありません。
HTTP/2のヘッダー圧縮には、状態を保持する必要があるという欠点があります[編集者注 – 圧縮/展開情報を格納するテーブルについて]。そのため、サーバーとクライアントは接続ごとに何らかの状態を保持する必要があり、HTTP/1接続の状態を保持する場合よりもはるかに多くのメモリを消費します。したがって、HTTP/2接続はそれぞれ、より多くのメモリを使用します。
8:40 HTTP/2の主な機能 – 優先順位付け

HTTP/2に関する最後の重要なポイントは、優先順位付けの仕組みです。これは、多重化によって生じる問題を解決します。接続が1つしかない場合、データの経路も1つしかないため、次にどのレスポンスをこの経路に送るかを慎重に判断する必要があります。
HTTP/2では優先順位付けは任意ですが、使用しなければパフォーマンス上のメリットはあまり得られません。NGINXのHTTP/2モジュールは優先順位付けを完全にサポートしており、重みと依存関係に基づく優先順位付けに対応しています。これまでに確認した限りでは、現時点で最速のHTTP/2実装です。以上がHTTP/2の要点です。
10:06 HTTP/2の歴史

これは、HTTP/2の歴史を簡単にまとめたスライドです。内容は比較的シンプルです。続いて、HTTP/2が実際にどのように動作するのかを見ていきましょう。
10:16 テストページ

さまざまなネットワーク条件下でHTTP/2がどのように動作するかを把握するため、一般的なWebページを使ってベンチマークを実施しました。これはGithubで見つけたHTTP/2ページです。リソースの数と各リソースのサイズを確認できます。一般的なサイトをかなりよく表していると思います。
10:52 テスト環境

テストを再現する場合に備えて、私のテスト環境をご紹介します。
11:02 DOM読み込み

こちらが得られた結果です。X軸では、さまざまなネットワーク遅延をミリ秒単位のラウンドトリップ時間(RTT)としてシミュレーションし、Y軸ではダウンロード時間を同じくミリ秒単位で測定しています。このテストでは、ページ上のすべてのリソースが完全に読み込まれるまでの時間をページ読み込み時間として測定しています。
グラフから、レイテンシが低い場合、HTTP、HTTPS、HTTP/2の間に大きな差はないという明確な傾向が見て取れます。レイテンシが高い場合は、暗号化されていないHTTP/1.xが最も高速で、次いでHTTP/2、HTTPSが最も低速です。
11:48 初回描画

「ファーストペイント」までの時間はどうでしょうか。これは、ユーザーが実際に画面上で何かを目にするまでの時間であるため、多くの場合、ユーザーの視点では最も重要な指標です。ページ全体の読み込みにかかる時間よりも、ユーザーが何かを目にするまでの時間のほうがはるかに重要な場合が多くあります。
ここでも同じ傾向が見られますが、今回のテストで興味深いのは、30 ms~250 msという中程度のレイテンシーでは、差はごくわずかなものの、HTTP/2が通常のHTTPよりも若干高速である点です。
12:45の構成

以上がベンチマーク結果です。続いて、HTTP/2とNGINXの設定方法について説明します。
実際のところ、設定は非常に簡単です。必要なのは、http2パラメーターをlistenディレクティブに追加することだけです。おそらく最も複雑なのは、最新バージョンのOpenSSLを入手する手順です。HTTP/2にはALPN[Application‑Layer Protocol Negotiation]拡張が必要であり、この拡張をサポートしているのはOpenSSL 1.0.2のみだからです。
HTTP/2向けにNPN[Next Protocol Negotiation]も実装しています。現時点ではほとんどのクライアントで動作しますが、2016年初頭にSPDYが非推奨となるため、各クライアントはNPNのサポートを終了する予定です。つまり、現時点では多くのLinuxディストリビューションに含まれるバージョンのOpenSSLでHTTP/2を使用できますが、近い将来、動作しなくなる点に注意が必要です。
以上で、HTTP/2向けのNGINXの設定についての説明と、私のプレゼンテーションを終わります。ありがとうございました。
[リファレンスドキュメント:HTTP/2 モジュール]
Q&A
Q: HTTP/2はクライアント側だけでなく、アップストリーム側でもサポートする予定ですか?
A: 現時点では、HTTP/2はクライアント側でのみサポートしています。proxy_passではHTTP/2を設定できません。[編集者注 – この記事の初版では、この文が誤って「 proxy_passでHTTP/2を設定できます」と記載されていました。これにより混乱を招いた可能性があることをお詫びいたします。]
では、バックエンド側でHTTP/2を使用することに、どのような意味があるのでしょうか。ベンチマークからもわかるように、アップストリーム接続のような低レイテンシのネットワークでは、HTTP/2を使用しても大きなメリットはありません。
また、NGINXにはkeepaliveモジュールがあり、keepaliveキャッシュを設定できます。HTTP/2の主なパフォーマンス上の利点は、追加のハンドシェイクを不要にできることです。ただし、keepaliveキャッシュですでにそれを実現している場合、アップストリーム側でHTTP/2を使用する必要はありません。
HTTP/2に関するその他のリソース
- Webアプリケーション開発者向けHTTP/2 – HTTP/2について知っておくべき情報を網羅したホワイトペーパー(PDF)
- ハイパフォーマンス・ブラウザ・ネットワーキング – GoogleのIlya Grigorikによる電子書籍の特別版
- HTTP/2の新機能 – 主な機能の解説と実装に関するアドバイスを提供するNGINXウェビナー
- HTTP/2のパフォーマンスを向上させる7つのヒント – ブログ記事
- List of HTTP/2をサポートするブラウザーの一覧 – Can I Use? Webサイト
お使いの環境でNGINX PlusによるHTTP/2を試してみませんか?今すぐ30日間の無料トライアルを開始するか、ユースケースについてお問い合わせください。
関連するブログ記事
チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する
OpenTelemetryを使用してNGINXサーバーの状態と健全性をより明確に把握することで、問題のトラブルシューティングを行い、Webアプリケーションのパフォーマンスを向上できます。
AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正
Akita SoftwareのAPIオブザーバビリティ向け新しいNGINX Plus Certified Moduleを活用して、APIエンドポイントの問題をより迅速に特定し、修正できます。
JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法
Red HatのシニアプリンシパルデベロッパーアドボケイトであるDaniel Oh氏が、Javaプロジェクトをゼロから構築するためのひな形を作成し、Kubernetesネイティブアプリケーションとしてビルドする方法を解説します。
F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング
NGINXaaS for Azureは、NGINX PlusをAzureネイティブのSaaSとして利用できるサービスです。NGINXの設定を容易にリフト&シフトできるため、クラウド導入とモダンアプリの展開を加速できます。

SELinuxでNGINXおよびNGINX Plusを使用する
Red Hat Enterprise Linux(RHEL)および関連ディストリビューションでSecurity-Enhanced Linux(SELinux)を有効にすると、デフォルト設定によりNGINXとNGINX Plusの一部の操作が制限されます。この記事では、すべての機能を利用できるようにSELinuxの設定を変更する方法について説明します。
NGINX PlusによるAWS Auto Scalingグループの負荷分散
新しいnginx-asg-sync統合ソフトウェアにより、NGINX PlusはAWS Auto Scalingグループの負荷を直接分散できるため、クラウドでの負荷分散がさらに柔軟になります