Search code examples
node.jsnode-cluster

Node Cluster: How to assign separate server/port to each worker?


I understand that I can use Nodes cluster module in order to create several workers all serving the same socket connection (example from docs):

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');
  });
} else {
  // 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);
}

However, what if I instead of serving the same connection want each worker to run their own server, each listening on a separate port?


Solution

  • You can pass environment variables to each child, allowing the master process to assign them ports:

    var cluster = require('cluster');
    var numCPUs = require('os').cpus().length;
    
    if (cluster.isMaster) {
      var pidToPort = {}; 
      var worker, port;
      for (var i = 0; i < numCPUs; i++) {
        port = 8000 + i;
        worker = cluster.fork({port: port});
        pidToPort[worker.process.pid] = port;
      }
    
      console.log(pidToPort);
    
      cluster.on('exit', function(worker, code, signal) {
        // Use `worker.process.pid` and `pidToPort` to spin up a new worker with
        // the port that's now missing.  If you do so, don't forget to delete the
        // old `pidToPort` mapping and add the new one.
        console.log('worker ' + worker.process.pid + ' died');
      }); 
    } else {
      // Start listening on `process.env.port` - but first, remember that it has
      // been cast to a string, so you'll need to parse it.
      console.log(process.env.port);
    }