How do I use Node.js clusters with my simple Express app? How do I use Node.js clusters with my simple Express app? express express

How do I use Node.js clusters with my simple Express app?


Actually, your workload is not really I/O bound: it is CPU bound due to the cost of jade-based dynamic page generation. I cannot guess the complexity of your jade template, but even with simple templates, generating HTML pages is expensive.

For my tests I used this template:

html(lang="en")  head    title Example  body    h1 Jade - node template engine    #container      ul#users        each user in items          li User:#{user}

I added 100 dummy strings to the items key in Redis.

On my box, I get 475 req/s with node.js CPU at 100% (which means 50% CPU consumption on this dual core box). Let's replace:

res.render( 'index', { items: items } );

by:

res.send( '<html lang="en"><head><title>Example</title></head><body><h1>Jade - node template engine</h1><div id="container"><ul id="users"><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li></ul></div></body></html>' );

Now, the result of the benchmark is close to 2700 req/s. So the bottleneck is clearly due to the formatting of the HTML page.

Using the cluster package in this situation is a good idea, and it is straightforward. The code can be modified as follows:

var cluster = require('cluster')if ( cluster.isMaster ) {  for ( var i=0; i<2; ++i )    cluster.fork();} else {  var      express = require( 'express' ),      app     = express.createServer(),      redis   = require( 'redis' ).createClient();  app.configure( function() {      app.set( 'view options', { layout: false } );      app.set( 'view engine', 'jade' );      app.set( 'views', __dirname + '/views' );      app.use( express.bodyParser() );  });  function log( what ) { console.log( what ); }  app.get( '/', function( req, res ) {      redis.lrange( 'items', 0, 50, function( err, items ) {            if( err ) { log( err ); } else {              res.render( 'index', { items: items } );            }      });  });  app.listen( 8080 );}

Now the result of the benchmark is close to 750 req/s with 100 % CPU consumption (to be compared with the initial 475 req/s).