Tornado vs PHP
Nginx + spawn-fcgi + PHP
vs.
Nginx + Tornado
どっちがいい?
テストしてきました
環境:
Centos 6 64Bit
必要なものインストール:
yum install spawn-fcgi
yum install nginx
spawn-fcgiの確認
$spawn-fcgi Usage: spawn-fcgi [options] [-- <fcgiapp> [fcgi app arguments]] spawn-fcgi v1.6.3 (ipv6) - spawns FastCGI processes ...(略)
#起動
$spawn-fcgi -a 127.0.0.1 -p 9000 -P /var/run/phpfcgi.pid -C 1 -f /usr/bin/php-cgi spawn-fcgi: child spawned successfully: PID: 61836
localhostの9000ポートで実行
#確認
$netstat --tcp -an -p | grep 9000 tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 61836/php-cgi
#nginxの確認
$nginx -v nginx version: nginx/1.6.2
#nginxの設定
/etc/nginx/conf.d/default.conf
の
server {
...
}
セクションの中に設定を入れる
設定対象項目:
listen 8081; #自由指定
server_name localhost; #IPでもOK
#PHPに置く場所
root /usr/share/nginx/html;
#URL最後は.phpのURLは127.0.0.1:9000のFCGIにて処理する
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
}
Nginx再起動
/etc/init.d/nginx restart
テスト用PHP作成
/usr/share/nginx/html/test.php
<?php echo "hello world\n" ?>
アクセス
http://192.168.183.138:8081/test.php
結果:
hello world
次は
tornado + nginx設定
1)作成
/usr/share/nginx/html/test.py
import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.write("hello world") application = tornado.web.Application([ (r"/tornado/test", MainHandler), ], debug=True) if __name__ == "__main__": application.listen(8889) tornado.ioloop.IOLoop.instance().start()
2)起動テスト
python test.py ※バックグラウンド起動 python test.py &>/dev/null &
3)URLテスト
http://192.168.183.138:8889/tornado/test
4)Nginx proxy設定(リバースプロキシ)
location /tornado/ {
proxy_pass http://127.0.0.1:8889;
}
5)アクセステスト
http://192.168.183.138:8081/tornado/test
tornado + nginx設定完了
負荷テスト:
httperf を利用する
php:
httperf --server 127.0.0.1 --port 8081 --uri /test.php --rate 100 --num-conn 1000 --num-call 10
tornado:
httperf --server 127.0.0.1 --port 8081 --uri /tornado/test --rate 100 --num-conn 1000 --num-call 10
HelloWorld出力のみの場合:
PHP:
Connection rate: 100.1 conn/s
Request rate: 1000.6 req/s (1.0 ms/req)
Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
Net I/O: 255.0 KB/s (2.1*10^6 bps)
Tornado:
Connection rate: 100.0 conn/s
Request rate: 999.8 req/s
Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
Net I/O: 289.0 KB/s
ここからは重要!!!!!!!!!!!!!
それぞれsleep(0.001)秒なら
実際はDBへのアクセスなどはどうしても待つ時間が発生するので
PHPコード:
<?php usleep(1000); echo "hello world\n" ?>
Torandoコード:
import tornado.ioloop import tornado.web from tornado.web import gen import time class MainHandler(tornado.web.RequestHandler): def slp(self, *args, **kwargs): time.sleep(0.001) return kwargs['callback']() @tornado.web.asynchronous @gen.coroutine def get(self): t = yield gen.Task(self.slp) self.write("hello world") application = tornado.web.Application([ (r"/tornado/test", MainHandler), ], debug=True) if __name__ == "__main__": application.listen(8889) tornado.ioloop.IOLoop.instance().start()
結果:
php
Connection rate: 4.9 conn/s
Reply status: 1xx=0 2xx=7806 3xx=0 4xx=0 5xx=1424
test-duration 203.834 s
Request rate: 46.2 req/s (21.7 ms/req)
tornado
Connection rate: 40.7 conn/s
Reply status: 1xx=0 2xx=8849 3xx=0 4xx=0 5xx=118
test-duration 24.600 s
Request rate: 369.3 req/s (2.7 ms/req)
この結果はびっくりしたけど
想定内です
※fcgi+php 1プロセス Tornadoは1プロセス
こんな結果出る原因は
tornadoは非同期Webサーバだから
参考まで・・・