SPDYも廃止されたのでnginxでhttp2使いたいけど、そもそもhttp2ってなに?っていうお話

こんにちは、高橋です。最近はnginxとrailsとswiftをぐるぐるしています。

nginxは非常にパワフルなwebサーバーで、アクセス数が増大した時した時でも非常に安定してトラフィックを捌いてくれています。

Ruby on Railsを使用する場合には、unicornやpumaなどのアプリケーションサーバーと併用して使うことが多いかと思いますが、どうしてもアプリケーションサーバーの方がボトルネックになってしまいます。nginxの処理能力をどれだけ極限まで高めても、結局はアプリケーションサーバーの方で処理しきれずに503が返ってきてしまうので、どうやってアプリケーションサーバーの方を安定的に処理能力をあげるか最近は悩むところです。。

 

最近ではAWSのEC2などでautoscalingもよく使われているので、1台あたりのトラフィックの処理能力はそれほどカリカリにまで高める必要はないのかもしれません。

 

ということで前置きはこんな所で、今回は(僕が勝手に)社内にもhttp2を取り入れたいなーと思い、色々調べてサーバー上で試験的に試してみたので、まとめてみました。

 

nginxでHTTP/2を使用する

Googleが提唱していたSPDYを取り込んだ形でhttp/2が標準化される流れとなり、これから本格的に広まって行きそうですが、nginxではバージョン1.9.5からhttp/2をサポートするようになりました。

HTTP/2とは

http/2は、http/1.1でプロトコルレベルでの問題となっていたデータ送受信における効率の悪さを克服する形で、http/1.1ではクライアントとサーバーがシングルシーケンスでデータをやりとりを行なっていたのが、http/2ではmultipleにシーケンスのやりとりを行うことができるようになりました。これによってデータ転送と処理の効率が上がりwebページを表示するまでのスピードが上がるというわけです。

http/1.1の場合 http/1.1ではブラウザのTCP同時接続は最大4~6に制限されています。 HTTP Head of Line Blockingによりブラウザのネットワークはこんな感じに、ひとつのファイルの読み込みが終わるまでは、それ以降のファイルの読み込みはブロックされます。

f:id:cluex-developers:20160928165756p:plain

   

http/2を使用した場合 同時に複数のファイルの読み込みを行うようになります。http/2ではブラウザの最大同時リクエスト数は100以上が可能とされていています。

f:id:cluex-developers:20160928165916p:plain

 

webブラウザのHTTP/2対応状況

2016年9月現在のブラウザの対応状況はこんな感じです。ChromeFirefoxなどのメジャーなブラウザではほぼほぼ対応していますが、IEsafariなどでは一部対応といった感じのようです。

Can I use... Support tables for HTML5, CSS3, etc f:id:cluex-developers:20160928203910p:plain

   

HTTP/1.1からHTTP/2への主な変更点

  • 根本となる部分はhttp/1.1と同じ
  • http/1.1のセマンティックスは変更しない
  • サーバーへのTCP接続数を1つに限定
  • TLSの機構を使用してプロトコルを自動選択
  • バイナリープロトコル
  • 多重化送信

などといったことが挙げられます。

HTTP/2を使用すると現在のTLSは一部機能が使用できない

よりセキュアな通信を確立するために、http/2は現在のTLSの一部機能を制限することで、セキュアなプロトコルとして現在は使用されています。今後http/2に対応した形の新しいTLS、もしくはそれに替わるものが出てくるかと思います。

制限される内容はこちら

  • プロトコル選択にはNPNではなくALPNを使用
  • サーバー認証を共有できる接続は接続共有が可能
  • TLSプロトコルは1.2以上のみが使用可能
  • TLS Compressionの禁止
  • Renegotiationの禁止
  • DH鍵は2048bit以上を使用
  • AEAD(認証付き暗号)のうち、GCMとCCM以外の暗号方式は利用できない

 

 

NPN (Next Protocol Negotiation) からALPN (Applicaiton-Layer Protocol Negotiation) へ

http/2に先行して、NPN (Next Protocol Negotiation) はTLS false start方式の次の規格としてgoogleが提唱し、SPDYを支える次期アプリケーション層プロトコルネゴシエーションとして2010年ごろに登場しました。

背景的にはwebサイトの表示速度にはネットワークの回線速度よりもRTTの影響が大きく関わっており、TCP接続のハンドシェイクを毎回行うところに非効率さがあったと判断したのかと思います。

これに関しては2011年にAkamaiが行なった調査を簡単にまとめた2012年の記事があるので、下記の引用画像を見ていただくとwebサイトの表示速度がRTT依存というのがよりわかりやすいかと思います。

f:id:cluex-developers:20160928235245p:plain 引用元: Latency: The New Web Performance Bottleneck - igvita.com

   

これまではNPNが使用されていましたが、今後の流れとしてはhttp/2での後押しもありALPNが一般的となりそうです。

   

NPNとALPNの簡単な違いは、サーバーとクライアントのどちらが使用するアプリケーションプロトコルの決定を行うかというところで、NPNではクライアント側によるプロトコルの選択が行われていましたが、ALPNではサーバー側がクライアントの使用できるアプリケーションプロトコルの中から使用するプロトコルを選択するという形になります。

 

ALPNを使用するにはOpenSSLのバージョン1.0.2以上が必要となりますが、サーバーのOSによっては最新のOpenSSLを入れてもALPNを使用できないこともあります。

   

CentOSでHTTP/2とALPNを使う

CentOSでhttp/2とALPNが使用できるのはCentOS 7 以上のバージョンとなります。

   

UbuntuでALPNを使う

Ubuntuでhttp/2とALPNを使用する場合は、今年リリースされた Ubuntu 16.04 LTS (Xenial) 以上のバージョンになります。

   

nginxでのhttp2を設定

現在、nginxでhttp/2を使うには、ngx_http_v2_moduleが必要となります。

Module ngx_http_v2_module

再ビルドなどに関しては他にも記事があるので割愛しますが、 サーバーのOSとOpenSSLのバージョンがhttp/2に対応していれば、nginxで使用するのは非常に簡単かと思います。

   

最後の最後で、もはやおまけみたいな感じになってしまいますが、listenディレクティブにhttp2と入れるだけで、基本的には完了です。

server {
  listen 443 ssl http2;

  # ~~~~~
}

付け加えるとしたら、SSLプロトコルの設定や、ssl_ciphersなどの設定などでしょうか。その辺りに関しましては、こちらの記事を流し読み程度にご参考にしていただけると嬉しいです。

cluex-developers.hateblo.jp

     

googleはもちろんのこと、facebooktwitterといった名だたるwebサービスで既にproductionへ導入されているhttp/2で、 徐々に様々なwebサービスで導入され始めていますが、本格的に普及するまではもうしばらく時間がかかりそうな気もします。

また進展があったら、記事にしたいと思います!

Cluexではエンジニアの方を探しています!

cluex.co.jp