Node.js vs Play vs SAStruts
前置き
Experiences with Node.js: Porting a RESTful Service Written in Java - ZiggyTech
上記記事では、実験的にJava (Jersey + Hibernate on Tomcat) で実装された REST API サーバを Node.js で書きなおしてみたら、少ないリソース(CPU/メモリ使用量)でほぼ同等のパフォーマンスが出せたよ(ただし、O/Rマッパーを使用しない場合)、と書いてあります。この件に関して @koichik さんとやり取りしていた中で以下のような意見を頂いたので、実際にやってみましたという記事です。
さすがに素の Struts 1.x は書き方も忘れたので、日本では結構採用事例があると思われる SAStruts と、最近仕事で使っている Play framework 1.2 を比較対象にします。
比較内容
/orders/ へのアクセスがあると、データベースに50件分のデータを検索しにいき、JSON の配列データに変換して返す REST API のスループット、および、その際の CPUとメモリ使用量を計測します。
実験に使ったソースは github においてあります。
hakobera/node-vs-sastruts-vs-playframework-rest-api-bench · GitHub
計測マシンのスペック
MacBook Pro 2011 early
計測対象の組み合わせ
- データベース
- PostgreSQL 9.1
- Node.js
- Node.js v0.6.12
- express 2.5.8
- pg 0.6.13 (JavaScript Pure Driver / SQL 直接実行, O/Rマッパーなし)
- Play
- Play framework 1.2.4
Java でGC が極端に発生しないようにヒープは最大 512MB を設定、何回は試行後、ヒープサイズが安定してから計測。それ以外はスレッドプールなどはデフォルト設定。全てプロダクションモードでの実行結果。
計測方法
元の記事では JMeter を使っていますが、JMeter だとそれ自体が結構リソースを食うので、今回は Apache Bench を利用しました。
ab -c 64 -n 5000 http://127.0.0.1:8080/orders/
スループットは上記コマンドを5回実行して、最大値と最小値を除く3回の平均値を採用。CPU 使用率とメモリ使用量はアクティビティモニタによる目測。
結果
スループット | CPU 使用率 | メモリ使用量 | スレッド数 | ||||||
Node.js | 488 (req/sec) | 100.6 (%) | 55.6 (MB) | 2 | |||||
Node.js (2 cluster) | 739 (req/sec) | 200.5(100.5 + 100.0) (%) | 115.7 (57.6+58.1) (MB) | 12(6*2) | |||||
Node.js (3 cluster) | 981 (req/sec) | 300.7(100.4 + 100.2 + 100.1) (%) | 167.1 (56.4+55.4+55.3) (MB) | 18(6*3) | |||||
Node.js (4 cluster) | 1129 (req/sec) | 400.8(100.0 + 100.3 + 100.3 + 100.2) (%) | 222.6 (55.6 + 55.4 + 55.7 + 55.9) (MB) | 24 (6*4) | |||||
SAStruts | 2237 (req/sec) | 388.6 (%) | 392.6 (MB) | 98 | |||||
Play | 906 (req/sec) | 557.8 (%) | 365.9 (MB) | 53 |
使っているものが色々と違うので直接は比較できないのですが、なんか元の記事とは傾向が異なる感じなりました。
【追記】github で cluster 化の プルリクエスト をもらったので、cluster のベンチを追加しました。4 cluster 以上は DBアクセスがネックになって、スループットは速くなったり、遅くなったりしてました。環境によっては 3,000 req/sec くらいまで伸びるようです。
まとめ
- Node.js
- Play
- 補足
- CPUコア数の多いマシンでは、シングルインスタンスの Node.js が、複数コアを利用できる SAStruts, Play に対しては圧倒的に遅い
- 2コアの MacBook Air で試してみると、SAStruts >> Play >= Node.js くらいにはなる
- Node.js は cluster での絶対性能の向上は図れると思うが、他の2つがデフォルトで複数コアを利用できるのに比べて、運用負荷がかかる