« previous

Secrets I wish I knew when starting Node.js

So when starting Node.js in production almost a year ago, we learned some tricks that we had to learn the hard way along the way. To clarify, for our API we use restify so in case you are wondering what server is in the example code.

1. Fail Hard and Loud!

Don’t try to prevent your Node app from crashing. It will crash and it will crash often. Our solution was to cluster and use forever behind nginx. Clustering is easy using the Cluster API. Use all your server CPUs to your advantage and spawn quickly when a worker dies.

EDIT

If you would like to cluster without code. Checkout out PM2 from Unitech instead of forever. I have actually moved to this when not using Docker.

var cluster = require('cluster');
var cCPUs   = require('os').cpus().length;

if( cluster.isMaster ){
  for( var i = 0; i < cCPUs; i++ ) {
    cluster.fork();
  }
  cluster.on('online', function ( worker ){
    console.log( 'Worker ' + worker.process.pid + ' started.' );
  });
  cluster.on( 'exit', function( worker, code, signal ) {
    console.log( 'Worker ' + worker.process.pid + ' died.' );
    cluster.fork();
  });
} else {
  server.listen(port, function() {
    console.log('%s listening at %s', server.name, server.url);
  });
}

This is useful only if you have more than one CPU on your server but its also good practice even if you have only one.

2. Learn DTrace!

We started with express for our API then I moved it over Restify really quickly because of DTrace. DTrace will make debugging your life so much easier. If you use express or even hapi, you can use this module.

3. Log everything.

There are serveral options for logging. We settled on Bunyan. Its command line tool makes reading JSON logs a blessing. We tried winston, connect logging but Bunyan was the best by far. We use Logstash in production but also put the logs in a rotating file. Here is a basis of what we implimented without Logstash. To add that, we just added a udp stream for that. If you need a module for adding the stream, this one worked for us, bunyan-logstash.

var restify = require('restify');
var bunyan = require('bunyan');
var logger = bunyan.createLogger({
	name: 'continu-api',
	streams: [{
		type: 'rotating-file',
		path: "somelogfile.log",
		period: '1d',   // daily rotation
		count: 4        // keep 3 back copies
	}],
	serializers: restify.bunyan.serializers
});

var server = restify.createServer({
  name: 'Continu API',
  log: logger
});

server.pre(function (req, res, next) {
  req.log.info({req: req}, 'START');
  return next();
});

There are several other things that have been helpful with production but those are the three biggest.

comments powered by Disqus