WEBサービスを構築する際に、基盤プラットフォームでの検討を行う事になった。
正直、言語はなんでもいいと考えていたのだが、WEB環境のシンプル構成はLAMPであった方が、色々と都合がいいと考えていたところ、SPA構成でNodejsを使いたいというエンジニアの声があり、とりあえずサーバーレスポンスをベンチして考えてみる事にする。
WIndows OSやMac OSサーバーを使う事はありえず、Linux OSでやる事は間違いないのだが、wordpressなどの導入を前提に考えると、LAMP環境しか有り得ず、各種言語のフレームワークを使うのであれば、言語環境に特化すれば良いだけなのだが、こうした決め事は、決めるべきエンジニアの経験値に依存する事になる。
今回ベンチマークを取ってその後その値だけで決める事はなく、基本的には、下記を比較して決めるのが懸命である。
速度クオリティ
移行のしやすさ
管理の簡易さ
指向性
WEBサービスのプラットフォームは、どういう構造で構築するのが良いかは、以下のような指向で考えたい。
・運用管理効率はLAMPが良い
・Nodejsはモジュール管理でサーバー問題がしょっちゅう発生する。
・複数の意図しないライブラリを引きずって管理していく事は、メンテデメリットでもある。
・会社としての開発部門を考えた時に、教育コストを抑えられた方が良い。
個人的には、CGI系は、Nodejs側でwrapできるが、NodejsはCGI系ではwrapしづらいという事も考慮して、基本はLAMPにしておいた方が無難な気がするが、そこはきちんとベンチを計測して判断していきたい。
ベンチ環境
とりあえず、実サーバーで行った方が性格なのだが、同一条件にする事で比較対象にはできるはずなので、下記の仮想環境で行ってみる。
端末 : Mac Booc 1.4GHz
OS : Docker ubuntu 14.1
Nodejs : v4.2.6
Nginx : nginx version: nginx/1.10.0 (Ubuntu)
PHP-fpm: PHP 7.0.22-0
処理速度のベンチ
単純にNodejsとPHP(fpm)の同じプログラムでの速度差をベンチマークしてみる。
ソースコード
var a = 0,
max = 10000000;
var start = Date.now();
for (var i = 0; i < max; i++) {
a += (i + 2 - 1 * 10 / 3) ;
}
var end = Date.now();
console.log(end - start);
console.log('end: ' + end);
console.log('start: ' + start);
<?php
$a = 0;
$max = 10000000;
$start = microtime(true)*1000;
for ($i = 0; $i < $max; $i++) {
$a += ($i + 2 - 1 * 10 / 3) ;
}
$end = microtime(true)*1000;
var_dump($end - $start);
var_dump('end: '.$end);
var_dump('start: '.$start);
var_dump('a: '.$a);
ベンチマーク実行
$ node bench.js
18
end: 1530577777756
start: 1530577777738
$ node bench.js
float(205.89086914062)
string(18) "end: 1530577822608"
string(22) "start: 1530577822402.1"
string(17) "a: 49999981664834"
この状態では"18:205"でNodejsが10倍以上早い速度結果に見えるが、計測値を同率にするために、Linuxのtimeコマンドで実施してみる。
$ time node bench.js
16
end: 1530577906828
start: 1530577906812
real 0m0.086s
user 0m0.060s
sys 0m0.020s
$ time php bench.php
float(207.77514648438)
string(20) "end: 1530577938348.9"
string(22) "start: 1530577938141.1"
string(17) "a: 49999981664834"
real 0m0.241s
user 0m0.210s
sys 0m0.020s
0.086s : 0.241s
という結果が出た事により、Nodejsが3倍ほどの速度優位があることがわかる。
htmlソース表示で比較
ソースコード
<!DOCTYPE html>
<html>
<head>
<script src="bench.js"></script>
</head>
<body>
<h1>Bench</h1>
</body>
</html>
var fs = require("fs");
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
var output = fs.readFileSync("sample.html" , "utf-8");
// var output = "<p>"+ req.url +"</p>";
res.end(output);
}).listen(3336);
<?php
echo file_get_contents("sample.html");
ベンチマーク実行
今回は、Nodejsでは、view.jsを3336ポートで起動しておいて、サイト運用に近い状態を構築する。
その時の100pvアクセスあった事を想定して、"ab(Apache Bench)"コマンドでアクセスしてみる。
あとは、sample.htmlとview.phpそれぞれにアクセスした場合を想定して、「Nginx」 , 「Nginx+PHP(fpm)」の比較も同時に行ってみる。
$ ab -n 1000 http://127.0.0.1:3336/
This is ApacheBench, Version 2.3 < $Revision: 1826891 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests
Server Software:
Server Hostname: 127.0.0.1
Server Port: 3336
Document Path: /
Document Length: 111 bytes
Concurrency Level: 1
Time taken for tests: 4.455 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 211000 bytes
HTML transferred: 111000 bytes
Requests per second: 224.48 [#/sec] (mean)
Time per request: 4.455 [ms] (mean)
Time per request: 4.455 [ms] (mean, across all concurrent requests)
Transfer rate: 46.26 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 1
Processing: 2 4 31.9 3 1012
Waiting: 2 4 31.9 3 1012
Total: 2 4 31.9 3 1012
Percentage of the requests served within a certain time (ms)
50% 3
66% 3
75% 4
80% 4
90% 4
95% 5
98% 6
99% 7
100% 1012 (longest request)
$ ab -n 1000 http://127.0.0.1/sample.html
This is ApacheBench, Version 2.3 < $Revision: 1826891 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Test aborted after 10 failures
apr_socket_connect(): Invalid argument (22)
yugetakoujinoMacBook:happywall yugeta$ ab -n 1000 http://127.0.0.1:80/sample.html
This is ApacheBench, Version 2.3 < $Revision: 1826891 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Test aborted after 10 failures
apr_socket_connect(): Invalid argument (22)
yugetakoujinoMacBook:happywall yugeta$ ab -n 1000 http://127.0.0.1/sample.html
This is ApacheBench, Version 2.3 < $Revision: 1826891 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests
Server Software: nginx/1.10.0
Server Hostname: 127.0.0.1
Server Port: 80
Document Path: /sample.html
Document Length: 111 bytes
Concurrency Level: 1
Time taken for tests: 2.645 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 352000 bytes
HTML transferred: 111000 bytes
Requests per second: 378.09 [#/sec] (mean)
Time per request: 2.645 [ms] (mean)
Time per request: 2.645 [ms] (mean, across all concurrent requests)
Transfer rate: 129.97 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 1
Processing: 2 2 0.8 2 13
Waiting: 2 2 0.8 2 13
Total: 2 3 0.8 2 13
WARNING: The median and mean for the total time are not within a normal deviation
These results are probably not that reliable.
Percentage of the requests served within a certain time (ms)
50% 2
66% 3
75% 3
80% 3
90% 4
95% 4
98% 5
99% 6
100% 13 (longest request)
$ ab -n 1000 http://127.0.0.1/view.php
This is ApacheBench, Version 2.3 < $Revision: 1826891 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests
Server Software: nginx/1.10.0
Server Hostname: 127.0.0.1
Server Port: 80
Document Path: /view.php
Document Length: 111 bytes
Concurrency Level: 1
Time taken for tests: 4.304 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 257000 bytes
HTML transferred: 111000 bytes
Requests per second: 232.34 [#/sec] (mean)
Time per request: 4.304 [ms] (mean)
Time per request: 4.304 [ms] (mean, across all concurrent requests)
Transfer rate: 58.31 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 3 4 3.8 4 120
Waiting: 3 4 3.8 4 120
Total: 3 4 3.8 4 120
Percentage of the requests served within a certain time (ms)
50% 4
66% 4
75% 4
80% 5
90% 5
95% 6
98% 7
99% 9
100% 120 (longest request)
数値の羅列だけで意味が分からない為少し解説すると、以下のような数値です。
処理時間
Nodejs : 1012 ms
Nginx : 13 ms
PHP : 120 ms
Nodejsは、ポート待ち受けをして、fsライブラリを使う為、段階が劇的に増えてしまったんでしょうね。
単純計算処理であれば、圧勝だったのに、HTMLソース表示は難ありな感じでした。
まとめ
プラットフォームは、どれか1つに決めずに、処理品質の高い物を部分的に使うのが、サービス提供には一番向いていると改めて思いました。
ただし、メンテナンスコストを考えるとどれか一つにした方がトラブル回避にも繋がります。
WEBサービスの基本はLAMPに任せて、SocketIOや、特殊なサーバーサイドJSを使うたい時にNodejsサーバー(同梱でも別立てでも可)を使うのが良いのではないでしょうか?
ちなみに、LAMPもPHP以外でもPythonやRubyやPerlでこだわってみるのも良いし、Goなどのコンパイル言語でゴリっと書き込んでみるのも楽しいかもしれませんね。
この辺は、機能追加や回収コストは高くつきそうですが・・・
どれを選ぶにしても一度作り始めるとなかなか変更ができないだけで、初期段階でしっかり検討しておきたいところですね。
0 件のコメント:
コメントを投稿