Heroku上でWordPressを動かしてチューニングしてみる

2017/03/03 追記: ab結果がおかしいのではというお話を頂き現在調査中です。あくまで参考値として参照ください。

2017/03/03 追記2: ab結果がおかしい事が判明した為、abの結果表示を削除しました。速度に関する記述に関しては夢物語としてお楽しみぐださい。

アプリケーションPaaSなHeroku上でWordPressを動かすという試みがあり、一応まともに動くという話を聞いたので、試してみるがてら高速化出来ないかやってみる。

インストール

雑にWordPressの公式からファイルをダウンロードし、

$ git add .
$ git commit -m "initial commit"

などとする。

WordPressMySQLを用意する方法はいくつかあるが、アドオンで人気そうなclearDBを使う。

$ heroku create
$ heroku addons:add cleardb

と打てば、herokuアプリを作成してclearDBアドオンも追加される。herokuコマンドのインストールなどは割愛する。

$ heroku config

とするとclearDBへの接続情報を得る事が出来るので、 wp-config.php ファイルに記載し、よしなに書き足す。

その後、 git push heroku master とすれば、WordPressが立ち上がる。意外と最初見た時は衝撃的だった。

チューニング & 計測

とりあえずデフォルトで計測を行う。

Nginx/PHP 5.6.30

※ab結果がおかしかった為削除(2017/03/03)

PHPバージョンアップ

HerokuではPHP7が動くので、こちらに移行する。 HerokuでPHPのバージョンを指定する場合はcomposer.lockを設定すれば良いらしいので、雑にcomposerを導入して、composer.jsonを書いて composer install した。

上手くPHP7系になった場合は、 git push heroku master の際に利用されるPHPのバージョンが表示されていて、そこに7系の数字が出るはず。

$ cat composer.json
{
    "name": "whywaita/test-wordpress",
    "authors": [
        {
            "name": "whywaita",
            "email": "whywaita@whywrite.it"
        }
    ],
    "require": {
      "php": "^7"
    }
}

abコマンドはこれも含めて最初と共通。

※ab結果がおかしかった為削除(2017/03/03)

そこそこ早くなった。

Apache

正直Nginxの方が早いと思うんだけど、一応試してみる。

Webサーバの設定は Procfile で行う。

$ cat Procfile
web: vendor/bin/heroku-php-nginx

$ cat Procfile
web: vendor/bin/heroku-php-apache2
※ab結果がおかしかった為削除(2017/03/03)

案の定少し遅くなった… これ以降はNginxに戻した。

SSL

SSL化はオーバーヘッドが生まれるものの速度の面でもそれなりに期待できるし、ちゃんとやるなら必須なので試してみる。

Herokuは *.herokuapp.com のwlidcard SSL証明書を提供しているので証明書自体は既に適用されているんだけど、これはHerokuのロードバランサーを介することで動いているもので、WordPressで安易にやると強制リダイレクトループしたりするので気を付ける。

この記事にも書いてあるんだけど、wp-config.phpをよしなに書くと動く。

具体的には以下のコードを追加すればいいんだけど、この時にwp-settings.phpの読み込みよりも上に書かないと詰まる。

/** ssl in heroku **/
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
      $_SERVER['HTTPS'] = 'on';

その件はこのブログにある。このページにアクセスする権限がありません。という表記が出たらこれで直る。

なので具体的にはこうなるのかな?

/** Absolute path to the WordPress directory. */
if ( !defined('ABSPATH') )
        define('ABSPATH', dirname(__FILE__) . '/');

/** ssl in heroku **/
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
      $_SERVER['HTTPS'] = 'on';

/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');

これを追加してHerokuにデプロイするととりあえずHTTPSでも動くようになる。が、デフォルトのドメインはHTTPのままで、管理画面とかもHTTPのままになるので、WordPressの管理画面から変更すると良い。

※ab結果がおかしかった為削除(2017/03/03)

猛烈に早くなった。SSL凄い。 Herokuではhttp2はまだサポートしていないので、これが対応されるとまだ早くなりそう。

詰まったところ

has exceeded the ‘max_questions’ resource (current value: 3600) エラー

突然WordPressのインストール画面が出てくるようになってしまって、再インストールしようとしたらこういうエラーが出る。

ClearDBのFAQにちゃんと書いてあって、1時間毎のクエリ数が制限されているらしい。

ClearDB FAQs – ClearDB

大体待ってると直るけど、ちゃんと動かすのなら課金するなりMySQLサーバを自分で立てるなりした方が良さそう。

参考記録

私がホスティングしているなぜにブログベンチマークも計測してみる。

$ ab -n 100 -c 100 https://blog.whywrite.it/
This is ApacheBench, Version 2.3 <$Revision: 1748469 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking blog.whywrite.it (be patient).....done


Server Software:        nginx
Server Hostname:        blog.whywrite.it
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256

Document Path:          /
Document Length:        70808 bytes

Concurrency Level:      100
Time taken for tests:   15.793 seconds
Complete requests:      100
Failed requests:        0
Total transferred:      7127500 bytes
HTML transferred:       7080800 bytes
Requests per second:    6.33 [#/sec] (mean)
Time per request:       15792.543 [ms] (mean)
Time per request:       157.925 [ms] (mean, across all concurrent requests)
Transfer rate:          440.74 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:      468  745 182.1    864     888
Processing:  1372 9285 4737.2  10609   14918
Waiting:     1340 9250 4736.6  10578   14888
Total:       1841 10030 4894.7  11472   15785

Percentage of the requests served within a certain time (ms)
  50%  11472
  66%  13843
  75%  14854
  80%  15274
  90%  15587
  95%  15655
  98%  15776
  99%  15785
 100%  15785 (longest request)

コンテンツ量もあるので一概に比較出来ないけど、実はHerokuの方が早いのかもしれない。

まとめ

とりあえずデフォルト設定と比較して約7倍ぐらい高速化できた。PaaS上でプラグイン利用無し縛りでやった分にはそれなりに高速化出来たような気がする。

Herokuは無料だとちょいちょい落ちたりしてるんだけど、その辺を許容するならかなり良い気がする。Herokuに信奉する人が何人か居るのは知っていて、そんなに良い物なのかと思っていたけど、最近そう言い出すのも少し分かるようになってきた気がする。

ちなみに今回のソースコードは以下に置いた。ClearDBのログイン情報がそのまま載ってるけど気にしないでください。

GitHub - whywaita/wordpress-heroku-sample

デモサイトは以下です。

https://yyta-wp.herokuapp.com/