注意
下記には、結構な量の嘘が混入されています。
詳細は、PHP BLT #2に行ってきたを参照下さい。
ちょっと遅くなりましたが、この記事はPHPアドベントカレンダー2015の17日目の記事です。
タイトルの件ですが、2015年12月現在で、PHPとWebサーバの組み合わせって、一体どんな構成にすると良いかな?と
ふと疑問に思ったので、自分の環境で、ベンチマークを取って見ることにしました。
ベンチマーク対象のPHP&Webサーバの組み合わせ
以下の4つの組み合わせでベンチを取って見ました。
1. NginxとPHP-FPM
近年、PHPでハイパフォーマンスを出すという場合によく取られる構成かと思います。
ISUCONに参加しているPHP系チームもこの構成を取るチームが多かったですね。
2. Apache2.4(prefork)とmod_php
これぞPHP!!という王道の構成です。
何も考えずにDocumentRootにphpファイルを放り込めば動きます。
3. Apache2.4(prefork)とmod_php with 静的ファイル用Nginx
ひとつ前の構成とほぼ同じですが、静的ファイルの処理用に前段にNginxを配置しています。
今回のベンチマークでは、Apacheを8080ポートで動かして、phpへのリクエストのみapache側にまわすようにしました。
理屈としては、mod_phpをロードしたApacheのプロセスが、静的ファイルの処理で使われないので、プロセスの無駄遣いが無くなります。
4. Apache2.4(event)とPHP-FPM
実は、今回はコレを試したくて、ベンチマークしたようなものでした。
Nginxに比べてどれくらいパフォーマンスが出るのか楽しみです。
ベンチマークを行った環境
実行したマシン
- マシン : MacBook Pro (メモリ16GB)
- 仮想サーバ : VirtualBox(Vagrant利用)
- CPU割当 : 1
- メモリ割り当て : 500MB
はい、すいません。普段、自分で持ち歩いているMacを使いました。
OS、その他ミドルウェア、PHPのバージョン
- Ubuntu14.04.3 LTS
- Apache2.4.17
- PHP 7.0.0
- Nginx 1.4.6
環境構築は、Vagrant+Ansibleを使っています。 今回のベンチマーク環境は、vagrant upで一発で構築出来ます。
Vagrantfileはこちら => https://github.com/hanhan1978/bench_vagrants
vboxsfが遅いので、nfsで共有フォルダをshareするように設定しています。
Apache, Nginx, PHPの設定はデフォルトのままです。特にいじらない状態で比較しています。
ベンチマークに利用したアプリケーション
簡単なToDoリストを表示するアプリをLaravelで作成しました。
Laravelの設定その他は、極力いじっていません。
/todoというURLにアクセスすると画像ファイルが12個と、jquery, cssを読み込んだ上で、DBに格納されたToDoリスト(全6件)を表示します。
リポジトリはこちら => https://github.com/hanhan1978/benchapp
ベンチマーカー
siegeを使いました。
siege -b -t60s -f urls.txt
urls.txtには、Todoリストを表示するURLと、ページ内の画像ファイル、CSS、JSのURLが列挙してあります。
一般的なウェブアプリと同じようなリクエストをWebサーバに対して行うようにしました。
リクエストは、各環境に対して3回ずつ行った上で、平均値を計算しました。(小数点二位以下は四捨五入)
※上記のVagranfileと同じリポジトリに、siegeの実行オプションを記述したテスト実行用のシェルが入ってます。
結果
個別の数値というよりは、他の環境との比較で見てもらうと良いかなと思います。
| NginxとPHP-FPM | Apache2.4(prefork)とmod_php | Apache2.4(prefork)とmod_phpとNginx | Apache2.4(event)とPHP-FPM
– | – | – | – | –
Transaction | 14427.33 | 11437.5 | 15220.25 | 10301.33
Availavility(%) | 100 | 100 | 100 | 100
Elapsed time(sec) | 59.84 | 59.5 | 59.14 | 59.39
Data Transferred(MB) | 868.29 | 648.97 | 916.46 | 583.83
Response Time(sec) | 0.067 | 0.08 | 0.063 | 0.09
Transaction rate(trans/sec) | 241.14 | 192.3 | 257.42 | 173.46
Throughput(MB/sec) | 14.51 | 10.91 | 15.50 | 9.83
Concurrency | 14.96 | 14.82 | 14.95 | 14.94
Successful Transactions | 14427.33 | 11437.5 | 15220.25 | 10301.33
Failed Transactions | 0 | 0 | 0 | 0
Longest Transaction | 2.54 | 7.73 | 3.17 | 2.51
Shortest transaction | 0 | 0 | 0 | 0
NginxとPHP-FPMの組合わせ、またはApache(prefork)とmod_php&前段Nginxの組み合わせが、好成績でした。
期待していたApache2.4のmpm_eventさんは、性能ふるわず!残念!
静的ファイルを混ぜたリクエストだったので、Apache(prefork)とmod_phpの組み合わせは、予想通り少し劣るという結果となりました。 ベンチマークを取り終わった後に、mpm_eventの設定を調整してみたのですが、結果はあまり変わらずだったので
mpm_event使いまくっている人は、なんか教えて下さい m(_ _)m
まとめ
結果としては、皆がなんとなく良いと思っているNginxとPHP-FPMの組み合わせは、静的ファイルも混ざった現実世界のウェブサービスのリクエストに対して、まあまあ良い性能を発揮するということが再確認できました。
意外とまではいかないのですが、mod_phpの前段にNginxで静的ファイルを捌くようにした構成も成績がよくて驚きました。preforkとmod_phpの組み合わせがPHPの処理ということに特化すれば、ちゃんとパフォーマンス出せるということを再認識できますね。
というわけで、今まで通り、何も考えずにNginxとPHP-FPM使うもよし、mod_php使うもよし。
ただし、静的ファイルがいっぱいあるときは、ちゃんと考えろよということで、オシマイでございます。
余談
静的ファイルのリクエストを止めて、PHPファイルだけのアクセスでベンチマークを取ると、どの環境でも大体同じくらいのレスポンスが出ました。
なので、このblogを読んで、「NginxとPHP-FPMにするんだ!」ではなくて、自分のサービスにくるリクエストの中身をきちんと計測した上でベターな選択肢を選んでいただければと思います。
ベンチマークやったの初めてなので、「ここはこうしたほうがいいよ」とか「これじゃ駄目じゃん」とかあったら、ジャカジャカご指摘下さいませ
m(_ _)m