Hi,
I've encountered a CPU issue which is somewhat of a puzzler for me.
Here's a description of what I'm doing: While investigating why an application written for Node.js was consuming what seemed to us as unreasonable amounts of CPU I ended up discovering that most of the CPU usage is actually attributed to framework we're using - Express.
I've validated this by comparing two "Hello World" style applications, both in single process mode and when using clustering.
I've implemented this super simple application using vanilla Node and then again using express:
Express version:
var express = require('express');
var app = express();
let userCount = 0;
app.get('/', function (req, res) {
userCount++;
const hello = {msg: "Hello world", userCount: userCount};
res.send(JSON.stringify(hello));
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
Plain Node version
var http = require('http');
let userCount = 0;
var server = http.createServer(function (request, response) {
userCount++;
response.writeHead(200, {"Content-Type": "application/json"});
const hello = {msg: "Hello world", userCount: userCount};
response.end(JSON.stringify(hello));
});
server.listen(3000);
console.log("Server running at http://127.0.0.1:3000/");
I've then used wrk2 from a load generator machine (c4.large - 2 CPUs) to send a constant load (2k reqs/sec) to the machine (another c4.large) running each of these 4 setups.
I was expecting to see higher CPU with express (after all it does more) and I was expecting the clustered versions to use somewhat more CPU than the single process versions.
What I actually saw was that indeed the express version uses more CPU than the plain Node version, but while the extra total CPU used when putting the plain Node version in a cluster was a bit higher, the same test for the Express version yielding MUCH more CPU.
Here are the grand totals in all cases this includes both CPUs:
- single process - plain Node version - total 12.95%
- 2 processes using Node's cluster module - plain Node version - total 14.52%
- single process - Express version - total 19.05%
- 2 processes using Node's cluster module - Express version - total 30.66%
So, the results for the plain Node version are consistent with what I was expecting, but the results for the Express version are not.
As an initial step, I'd like to understand why does putting the same code inside a cluster perform so much worse when using express.
So I'm wondering regarding two things:
- Are my assumption even correct? Perhaps with increased processing it IS actually expected to see such deterioration when moving from single to clustered?
- If my assumption is correct, which tools (if any...) can I use to diagnose this so I'll know what to look for when I dive into the code. My initial intuition was increased context switches, but looking at vmstat output I could not find proof for that.