Currently, my prod environment for a side project is a git repo, where I pull in some code, manually kill the server with Ctrl-C, and restart it manually.
I realize there are a lot of things wrong with this. For instance, what if a user is still in the middle of doing something important and the process is crunching sensitive data, and I just killed it?!
When I used node v0.4.x there was a nice Cluster module that could restart the server gracefully, when the application is in a quiet state. In v0.6.x the Cluster module is built into node, but it's really, really bare, and doesn't have the graceful restart ability.
Anyone know how I can gracefully restart a nodejs server in v0.6.x?
js server with nodemon. In this case, if we make any changes to the project then we will have to restart the server by killing it using CTRL+C and then typing the same command again. It is a very hectic task for the development process.
A graceful shutdown is when a computer is turned off by software function and the operating system (OS) is allowed to perform its tasks of safely shutting down processes and closing connections. A hard shutdown is when the computer is forcibly shut down by interruption of power.
You can handle POSIX signals in node code.
See in the example code, that will handle SIGINT (Ctrl-C for instance) as a STOP signal for all cluster workers, and SIGUSR2 will just restart all workers
So, issuing kill -SIGUSR2 PID
, where PID is node master PID will restart all cluster
module.exports = function(app) { var cluster = require('cluster'); var numCPUs = require('os').cpus().length; var workerList = new Array(); var sigkill = false; if (cluster.isMaster) { for (var i = 0; i < numCPUs; i++) { var env = process.env; var worker = cluster.fork(env); workerList.push(worker); } process.on('SIGUSR2',function(){ console.log("Received SIGUSR2 from system"); console.log("There are " + workerList.length + " workers running"); workerList.forEach(function(worker){ console.log("Sending STOP message to worker PID=" + worker.pid); worker.send({cmd: "stop"}); }); }); process.on('SIGINT',function(){ sigkill = true; process.exit(); }); cluster.on('death', function(worker) { if (sigkill) { logger.warn("SIGKINT received - not respawning workers"); return; } var newWorker = cluster.fork(); console.log('Worker ' + worker.pid + ' died and it will be re-spawned'); removeWorkerFromListByPID(worker.pid); workerList.push(newWorker); }); } else { process.on('message', function(msg) { if (msg.cmd && msg.cmd == 'stop') { console.log("Received STOP signal from master"); app.close(); process.exit(); } }); app.listen(3000); } function removeWorkerFromListByPID(pid) { var counter = -1; workerList.forEach(function(worker){ ++counter; if (worker.pid === pid) { workerList.splice(counter, 1); } }); } }
There's a module named Forever.
That can gracefully restart the process. I suppose then you can somehow run several instances with cluster (one on each core) and use Forever to monitor / restart them.
This is just an option I found; I'm open to suggestions!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With