I am doing a quick performance test for NodeJS vs. Java. The simple use case chosen is querying a single table in MySQL database. The initial results were as follows:
Platform | DB Connections | CPU Usage | Memory Usage | Requests/second
==============================|================|===========|===============|================
Node 0.10/MySQL | 20 | 34% | 57M | 1295
JBoss EAP 6.2/JPA | 20 | 100% | 525M | 4622
Spring 3.2.6/JDBC/Tomcat 7.0 | 20 | 100% | 860M | 4275
Note that Node's CPU and memory usage are way lower than Java but the throughput is also about a third! Then I realized that Java was utilizing all four cores on my CPU, whereas Node was running on only one core. So I changed the Node code to incorporate the cluster module and now it was utilizing all four cores. Here are the new results:
Platform | DB Connections | CPU Usage | Memory Usage | Requests/second
==============================|================|===========|===============|================
Node 0.10/MySQL (quad core) | 20 (5 x 4) | 100% | 228M (57 x 4) | 2213
Note that the CPU and memory usage have now gone up proportionately but the throughput has only gone up by 70%. I was expecting a four fold increase, exceeding the Java throughput. How can I account for the descrepancy? What can I do to increase the throughput linearly?
Here's the code for utilizing multiple cores:
if (Cluster.isMaster) {
var numCPUs = require("os").cpus().length;
for (var i = 0; i < numCPUs; i++) {
Cluster.fork();
}
Cluster.on("exit", function(worker, code, signal) {
Cluster.fork();
});
}
else {
// Create an express app
var app = Express();
app.use(Express.json());
app.use(enableCORS);
app.use(Express.urlencoded());
// Add routes
// GET /orders
app.get('/orders', OrderResource.findAll);
// Create an http server and give it the
// express app to handle http requests
var server = Http.createServer(app);
server.listen(8080, function() {
console.log('Listening on port 8080');
});
}
I am using the node-mysql driver for querying the database. The connection pool is set to 5 connections per core, however that makes no difference. If I set this number to 1 or 20, I get approximately the same throughput!
var pool = Mysql.createPool({
host: 'localhost',
user: 'bfoms_javaee',
password: 'bfoms_javaee',
database: 'bfoms_javaee',
connectionLimit: 5
});
exports.findAll = function(req, res) {
pool.query('SELECT * FROM orders WHERE symbol="GOOG"', function(err, rows, fields) {
if (err) throw err;
res.send(rows);
});
};