I am comparatively new to node.js. And I have a question related to it. As far as I understand, node.js use event driven paradigm, so it spawns only a single thread and handles everything asynchronously(event driven fashion). This helps it consuming less resources and handling lots of simultaneous connections.
However, I have one question related to that, since it has only one thread, even a single unhandled exception could crash everything isn't it. Unlike node.js webserver like apache which can use multiple processes to handled multiple connections, even if one process crashes it doesn't matter.
So, I am bit concerned whether node.js is good for that. I am just a beginner. So any insights will be helpful
Let's use an analogy to explain this relatively newfangled technology: A record player and ten users:
PHP Multithreaded: 10 record players, each player has one arm+needle, each user has one record player. Each user plays a few notes off their own record player. Unhandled exception, or hissing notes=record player keeps playing until user lifts arm/Process closed. Nobody else can hear it because they have their own record player. And they're wearing headphones.
NodeJS: Single Threaded
One record player, with 10 arm+needles, one for each user, and they're all sharing that one record player. Each user accesses a quick few notes, a process, off the record at the same time. It's asynchronous, everybody gets a piece of the music. An unhandled exception= hissing notes for the one user, only those accessing the same few notes, or same process that throws the exception will hear the hissing too. But that's about it. Everyone else will still hear the sweet music. They still have their own headphones.
K. No more bad analogy.
Here's the solution to your hypothetical problem: In Node.js, you can attach a listener to the `uncaughtException" event. So you can kill the offending process if it would, or could, in the rare event, take down the server.
I use Cluster to get around the single threaded reliability issue. Cluster is one of the built in libraries and you can configure it to launch one or (n) number of worker instances. Typically you launch an instance for every CPU core in the server. The main process monitors events from the worker processes (I am not sure process is 100% the correct term) and can catch terminations, log them, and than restart the workers. Ideally you will also want to have multiple web servers regionally located and a load balancer that can monitor your web servers, detect when they are overloaded or not responding and take appropriate actions such as launching new instances and killing dead ones
Typical code to use cluster looks like this (based on example in the cluster documentation):
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
// restart this instance
cluster.fork();
});
} else {
// create an error handler for uncaught exceptions so we can log them
process.on('uncaughtException', function(err) {
var date = new Date ();
var message = date.toString () + ":UNCAUGHT EXCEPTION\n" + err.stack + "\n";
console.log (message);
process.exit(1); // we will get restarted by the cluster process
});
// Workers can share any TCP connection
// In this case its a HTTP server
http.createServer(function(req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
}