リクルート住まいカンパニー Tech Blog

ITのちからで暮らしをよくしたい、エンジニア・デザイナーが発信するTech情報メディア

テックブログをHTTP/2 + PHP7 + Wordpressで構築してみた

f:id:recruit-sumai:20170309111616p:plain

こんにちは。スマホ最適化サイトの開発チームに所属している新人エンジニアの上野です。

今回、リクルート住まいカンパニーでテックブログを公開するにあたり、 栄誉あることにサイトの構築を行わせて頂きました。

構築するにあたりテックブログらしく(?)、比較的新しい技術導入して構築しようと考え、HTTP/2PHP7を用いて構築しました。

HTTP/2

「HTTP」の新しいバージョンであり、

  • 1コネクション内での多重化
  • サーバプッシュ

などの仕様が組み込まれています。

1コネクション内での多重化」は1つのTCPコネクションの内部に複数チャネルを作成することで実現しています。 これにより、ブラウザによる同時接続数の制限も受けなくなり、リソースの結合も不要になります。

サーバプッシュ」は1つ前のクライアントからのリクエストを元に、次のリクエストを先取りしてレスポンスを返すといったものです。 サーバからプッシュされたコンテンツはクライアント側でキャッシュされ、クライアントはキャッシュからコンテンツを読み込むことで実現しています。

上記の2点により、HTTP/2でWeb表示の更なる高速化が期待されています。

HTTP/2は現在(2015月12月20日)、Firefox/Google Chrome/Internet Explorerなどで利用可能な状況となっています。 f:id:recruit-sumai:20170307180020p:plain (引用:http://caniuse.com/#search=http%2F2

PHP7

php7

PHP5との互換性を維持しつつ、従来のPHP5と比べて2倍以上の性能向上メモリ使用量を低減するなど、大きな改善が実現されているようです。 構築期間中の11月26日にはPHP7.0.0RC8が公開され、12月3日には正式にPHP7.0.0がリリースされました。 今回のサイト構築ではPHP7.0.0を採用しています。

インフラ構成図

f:id:recruit-sumai:20170307180504p:plain

構成要素は以下になります。*()内はバージョン

  • h2o(1.6.0)
  • nginx(1.9.9)
  • php7(7.0.0)
  • wordpress(4.4)

現段階でElastic Load BalancerがHTTP/2未対応であるため、Layer4のELBとリバースプロキシでHTTP/2を実現しています。

h2oでのHTTP/2

HTTP/2 Server Pushでcss, jsなどのファイルをプッシュする際に、ブラウザがキャッシュしているファイルもプッシュしてしまうと、帯域を無駄に消費するだけでなく、レスポンス時間にも悪影響を与えてしまいます。

h2oではCASPER(cache-aware server pusher)という方式でこの問題を解消しています。 簡単に説明すると、CASPERではCookieを使用してwebブラウザのキャッシュ状態を監視し、キャッシュされていないファイルのみをプッシュするようにしています。

mruby handlerでリクエストを受け取った際、デリゲートにファイルのプッシュを行わせています。 また、http2-casperディレクティブをONにして、キャッシュされているファイルのプッシュを破棄するように設定しています。

...(省略)...

"my host":
    listen:
      host: 0.0.0.0
      port: 443
      ssl:
        ...

    proxy.timeout.io: 30000
    proxy.timeout.keepalive: 1000

    paths:
      "/":
        mruby.handler-file: /path/to/server_push.rb
        proxy.reverse.url: http://#{WebサーバーのURL}/

# ★CAPSERを利用し、未キャッシュファイルのPUSHを有効にする設定
http2-casper: ON
http2-reprioritize-blocking-assets: ON

...(省略)...

実際の通信は以下のようになっています。

まずは、HTTP/2を使用していない時の通信が以下になります。 (h2oを使用せずに、nginxをリバースプロキシとして使用しています。) f:id:recruit-sumai:20170307180814p:plain 緑の部分がサーバから返却されるまでの時間(Time To First Byte)で、青の部分がコンテンツをダウンロードする時間です。 CDNを使用していないため、緑と青のラインの並列数が最大で6つとなっています。

次に、h2oを使用したHTTP/2での1コネクション内での多重化を行っている時の通信が以下になります。 f:id:recruit-sumai:20170307180946p:plain 図の下部を見ると分かる通り、ストリーム間の優先付の関係上、並列に処理されていない部分もあります。

最後にh2oのCasper(Server Push)を使用した時の通信が以下になります。 f:id:recruit-sumai:20170307181924p:plain ブラウザがリクエストし、サーバが返却されたhtmlファイルを読み込み、その中のcss/jsなどのファイルをリクエストする前にサーバ側からプッシュされるため、上記のような結果になっています。 (*図に記載してあるとおり、ブラウザがキャッシュから取得しているわけではありません)

今回、Reverse Proxyにh2oを使用でHTTP/2プロトコルに対応させるだけでなく、h2oのCasper(Server Push)を使用することで更なる高速化が可能なことがわかりました。

次回は、HTTP/2とPHP7を導入することでどの程度の速度改善がなされたのか検証したいと考えています。

参考