Edit (2): Now use db-mysql with the generic-pool module. The error rate has decreased significantly and fluctuates by 13%, but the throughput is still around 100 req / sec.
Edit (1): After someone suggested that ORDER BY RAND () would cause MySQL to be slow, I removed this sentence from the query. Node.js now fluctuates around 100 req / sec, but still the server reports an error CONNECTION: Too many connections.
Node.js or Lighttpd with PHP?
You probably saw a lot of Hello World Node.js ... tests, but the hello world tests, even those that were delayed for 2 seconds per request, are not even close to real world use. I also performed these variations of the Hello World tests using Node.js and a pilot throughput of about 800 req / sec with an error rate of 0.01%. However, I decided on some tests that were a bit more realistic.
Maybe my tests are not completed, most likely something is REALLY wrong with Node.js or my test code, so if your Node.js expert, please help me write some better tests. My results are published below. I used Apache JMeter for testing.
Test Case and System Specifications
The test is pretty simple. The mysql query for the number of users is randomly ordered. The first username of the user is retrieved and displayed. The connection to the mysql database is through a unix socket. OS - FreeBSD 8+. 8 GB of RAM. Intel Xeon Quad Core 2.x Ghz processor. I tweaked Lighttpd configurations a bit before I came across Node.js.
Apache JMeter Settings
The number of threads (users): 5000 I believe that this is the number of simultaneous connections
Acceleration Period (in seconds): 1
Number of cycles: 10 This is the number of requests per user
Apache JMeter End Results
Label | # Samples | Average | Min | Max | Std. Dev. | Error% | Throughput | KB / sec | Avg. Bytes
HTTP Requests Lighttpd | 49918 | 2060ms | 29ms | 84790ms | 5524 | 19.47% | 583.3 / sec | 211.79 | 371.8
HTTP Requests Node.js | 13767 | 106569ms | 295ms | 292311ms | 91764 | 78.86% | 44.6 / sec | 79.16 | 1816
Output Results
Node.js was so bad that I had to stop the test earlier. [ Fixed Tested fully]
Node.js reports a "CONNECTION: too many connections" error on the server. [ Fixed ]
In most cases, Lighttpd had a throughput of about 1200 req / sec.
However, Node.js had a throughput of about 29 req / sec. [ Fixed Now at 100req / sec]
This is the code I used for Node.js (using MySQL pools)
var cluster = require('cluster'), http = require('http'), mysql = require('db-mysql'), generic_pool = require('generic-pool'); var pool = generic_pool.Pool({ name: 'mysql', max: 10, create: function(callback) { new mysql.Database({ socket: "/tmp/mysql.sock", user: 'root', password: 'password', database: 'v3edb2011' }).connect(function(err, server) { callback(err, this); }); }, destroy: function(db) { db.disconnect(); } }); var server = http.createServer(function(request, response) { response.writeHead(200, {"Content-Type": "text/html"}); pool.acquire(function(err, db) { if (err) { return response.end("CONNECTION error: " + err); } db.query('SELECT * FROM tb_users').execute(function(err, rows, columns) { pool.release(db); if (err) { return response.end("QUERY ERROR: " + err); } response.write(rows.length + ' ROWS found using node.js<br />'); response.end(rows[0]["username"]); }); }); }); cluster(server) .set('workers', 5) .listen(8080);
This is the code I used for PHP (Lighttpd + FastCGI)
<?php $conn = new mysqli('localhost', 'root', 'password', 'v3edb2011'); if($conn) { $result = $conn->query('SELECT * FROM tb_users ORDER BY RAND()'); if($result) { echo ($result->num_rows).' ROWS found using Lighttpd + PHP (FastCGI)<br />'; $row = $result->fetch_assoc(); echo $row['username']; } else { echo 'Error : DB Query'; } } else { echo 'Error : DB Connection'; } ?>