Deep Dive Into Node.js and MongoDB - Day 7
Introduction
In case you missed the other days:
Day 1 Deep Dive
Day 2 Deep Dive with MongoDB
Day 3 Deep Dive with MongoDB
Day 4 Deep Dive with MongoDB
Day 5 Deep Dive with MongoDB
Day 6 Deep Dive with MongoDB
As mentioned yesterday I wanted to abstract out the config settings and look into a way to better take advantage of the hardware at my disposal like I can with ASP.NET. Node.js being single threaded has a huge disadvantage when run on a multi-core server (as most are these days). Knowing there were work arounds I was keen to figure out what they were and then compare the "out of the box" mode verses using multiple cpus.
Prerequisites
As mentioned previously, this point I am going to assume MongoDB is up and running, if you do not, check my
first day post for details on how to get it up and running.
Config
I read a couple different approaches in the Node.js world on configs. Some prefered a json configuration file as I have gotten use to ASP.NET Core while others prefered to just use a JavaScript file with
module.exports
to expose config values. For the sake of this test app at this point I went with the latter:
module.exports = {
DATABASE_CONNECTIONSTRING: 'localhost/dayinnode',
HTTP_SERVER_PORT: 1338
};
And then in my
dbFactory.js
:
var settings = require('./config');
mongoose.connect('mongodb://' + settings.DATABASE_CONNECTIONSTRING);
This way I can keep my code free of magic strings, while still having all of my configuration settings in one file.
Cluster
As it would turn out, Node.js had a built in module called
Cluster that as the name would imply adds support for creating child processes of node.js.
To get it up and running was pretty painless, just a simply require on cluster and then a check to get the number of cpus. I took it one step further and abstracted away the actual "worker" code into the
worker.js
file. The
server.js
file now looks like this:
var cluster = require("cluster");
cluster.setupMaster({
exec: 'worker.js',
silent: true
});
var numCPUs = require("os").cpus().length;
if (cluster.isMaster) {
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on("exit", function (worker, code, signal) {
cluster.fork();
});
}
In doing comparisons between the single threaded approach and the new cluster approach there wasn't a distinguishable difference, which leads me to believe at least on my 2014 Razer Blade laptop the bottleneck is the
MongoDB
database not node.js.
Next up...
When I get back home I hope to test this new code on my i7 desktop to see if there is any discernable difference between the cluster approach and the single threaded approach when using a
MongoDB
database. In addition, ensure that
MongoDB
is configured properly with Mongoose since the ASP.NET Core performance exceeded node.js's.
All of the code thus far is committed on
GitHub.