0
0
mirror of https://github.com/nodejs/node.git synced 2024-11-29 23:16:30 +01:00
nodejs/doc/api/cluster.markdown
isaacs 1d5b6f26fe Merge remote-tracking branch 'ry/v0.6' into v0.6-merge
Conflicts:
	ChangeLog
	Makefile
	deps/npm/AUTHORS
	deps/npm/html/api/bin.html
	deps/npm/html/api/bugs.html
	deps/npm/html/api/commands.html
	deps/npm/html/api/config.html
	deps/npm/html/api/deprecate.html
	deps/npm/html/api/docs.html
	deps/npm/html/api/edit.html
	deps/npm/html/api/explore.html
	deps/npm/html/api/help-search.html
	deps/npm/html/api/init.html
	deps/npm/html/api/install.html
	deps/npm/html/api/link.html
	deps/npm/html/api/load.html
	deps/npm/html/api/ls.html
	deps/npm/html/api/npm.html
	deps/npm/html/api/outdated.html
	deps/npm/html/api/owner.html
	deps/npm/html/api/pack.html
	deps/npm/html/api/prefix.html
	deps/npm/html/api/prune.html
	deps/npm/html/api/publish.html
	deps/npm/html/api/rebuild.html
	deps/npm/html/api/restart.html
	deps/npm/html/api/root.html
	deps/npm/html/api/run-script.html
	deps/npm/html/api/search.html
	deps/npm/html/api/shrinkwrap.html
	deps/npm/html/api/start.html
	deps/npm/html/api/stop.html
	deps/npm/html/api/submodule.html
	deps/npm/html/api/tag.html
	deps/npm/html/api/test.html
	deps/npm/html/api/uninstall.html
	deps/npm/html/api/unpublish.html
	deps/npm/html/api/update.html
	deps/npm/html/api/version.html
	deps/npm/html/api/view.html
	deps/npm/html/api/whoami.html
	deps/npm/html/doc/README.html
	deps/npm/html/doc/adduser.html
	deps/npm/html/doc/bin.html
	deps/npm/html/doc/bugs.html
	deps/npm/html/doc/build.html
	deps/npm/html/doc/bundle.html
	deps/npm/html/doc/cache.html
	deps/npm/html/doc/changelog.html
	deps/npm/html/doc/coding-style.html
	deps/npm/html/doc/completion.html
	deps/npm/html/doc/config.html
	deps/npm/html/doc/deprecate.html
	deps/npm/html/doc/developers.html
	deps/npm/html/doc/disputes.html
	deps/npm/html/doc/docs.html
	deps/npm/html/doc/edit.html
	deps/npm/html/doc/explore.html
	deps/npm/html/doc/faq.html
	deps/npm/html/doc/folders.html
	deps/npm/html/doc/help-search.html
	deps/npm/html/doc/help.html
	deps/npm/html/doc/index.html
	deps/npm/html/doc/init.html
	deps/npm/html/doc/install.html
	deps/npm/html/doc/json.html
	deps/npm/html/doc/link.html
	deps/npm/html/doc/list.html
	deps/npm/html/doc/npm.html
	deps/npm/html/doc/outdated.html
	deps/npm/html/doc/owner.html
	deps/npm/html/doc/pack.html
	deps/npm/html/doc/prefix.html
	deps/npm/html/doc/prune.html
	deps/npm/html/doc/publish.html
	deps/npm/html/doc/rebuild.html
	deps/npm/html/doc/registry.html
	deps/npm/html/doc/removing-npm.html
	deps/npm/html/doc/restart.html
	deps/npm/html/doc/root.html
	deps/npm/html/doc/run-script.html
	deps/npm/html/doc/scripts.html
	deps/npm/html/doc/search.html
	deps/npm/html/doc/semver.html
	deps/npm/html/doc/shrinkwrap.html
	deps/npm/html/doc/star.html
	deps/npm/html/doc/start.html
	deps/npm/html/doc/stop.html
	deps/npm/html/doc/submodule.html
	deps/npm/html/doc/tag.html
	deps/npm/html/doc/test.html
	deps/npm/html/doc/uninstall.html
	deps/npm/html/doc/unpublish.html
	deps/npm/html/doc/update.html
	deps/npm/html/doc/version.html
	deps/npm/html/doc/view.html
	deps/npm/html/doc/whoami.html
	deps/npm/lib/install.js
	deps/npm/lib/ls.js
	deps/npm/man/man1/npm.1
	deps/npm/man/man1/shrinkwrap.1
	deps/npm/man/man3/npm.3
	deps/npm/man/man3/shrinkwrap.3
	deps/npm/node_modules/request/main.js
	deps/npm/node_modules/request/package.json
	deps/npm/package.json
	deps/uv/src/unix/core.c
	deps/v8/src/conversions-inl.h
	deps/v8/src/elements.cc
	deps/v8/src/version.cc
	doc/about/index.html
	doc/api/assert.markdown
	doc/api/child_process.markdown
	doc/api/cluster.markdown
	doc/api/crypto.markdown
	doc/api/debugger.markdown
	doc/api/dgram.markdown
	doc/api/dns.markdown
	doc/api/documentation.markdown
	doc/api/events.markdown
	doc/api/fs.markdown
	doc/api/globals.markdown
	doc/api/http.markdown
	doc/api/https.markdown
	doc/api/modules.markdown
	doc/api/net.markdown
	doc/api/os.markdown
	doc/api/path.markdown
	doc/api/process.markdown
	doc/api/querystring.markdown
	doc/api/readline.markdown
	doc/api/stdio.markdown
	doc/api/stream.markdown
	doc/api/timers.markdown
	doc/api/tls.markdown
	doc/api/tty.markdown
	doc/api/url.markdown
	doc/api/util.markdown
	doc/api/vm.markdown
	doc/api/zlib.markdown
	doc/api_assets/style.css
	doc/community/index.html
	doc/index.html
	doc/logos/index.html
	doc/template.html
	src/node_version.h
	tools/doc/html.js
	tools/gyp/test/mac/app-bundle/empty.c
2012-03-03 23:38:52 -08:00

9.6 KiB
Raw Blame History

Cluster

Stability: 1 - Experimental

A single instance of Node runs in a single thread. To take advantage of multi-core systems the user will sometimes want to launch a cluster of Node processes to handle the load.

The cluster module allows you to easily create a network of processes that all share server ports.

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('death', function(worker) {
    console.log('worker ' + worker.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);
}

Running node will now share port 8000 between the workers:

% node server.js
Worker 2438 online
Worker 2437 online

This feature was introduced recently, and may change in future versions. Please try it out and provide feedback.

cluster.settings

  • {Object}
    • exec {String} file path to worker file. (Default=__filename)
    • args {Array} string arguments passed to worker. (Default=process.argv.slice(2))
    • silent {Boolean} whether or not to send output to parent's stdio. (Default=false)

All settings set by the .setupMaster is stored in this settings object. This object is not supposed to be change or set manually, by you.

cluster.isMaster

  • {Boolean}

True if the process is a master. This is determined by the process.env.NODE_UNIQUE_ID. If process.env.NODE_UNIQUE_ID is undefined, then isMaster is true.

cluster.isWorker

  • {Boolean}

This boolean flag is true if the process is a worker forked from a master. If the process.env.NODE_UNIQUE_ID is set to a value, then isWorker is true.

Event: 'fork'

  • worker {Worker object}

When a new worker is forked the cluster module will emit a 'fork' event. This can be used to log worker activity, and create you own timeout.

var timeouts = [];
var errorMsg = function () {
  console.error("Something must be wrong with the connection ...");
});

cluster.on('fork', function (worker) {
  timeouts[worker.uniqueID] = setTimeout(errorMsg, 2000);
});
cluster.on('listening', function (worker) {
  clearTimeout(timeouts[worker.uniqueID]);
});
cluster.on('death', function (worker) {
  clearTimeout(timeouts[worker.uniqueID]);
  errorMsg();
});

Event: 'online'

  • worker {Worker object}

After forking a new worker, the worker should respond with a online message. When the master receives a online message it will emit such event. The difference between 'fork' and 'online' is that fork is emitted when the master tries to fork a worker, and 'online' is emitted when the worker is being executed.

cluster.on('online', function (worker) {
  console.log("Yay, the worker responded after it was forked");
});

Event: 'listening'

  • worker {Worker object}

When calling listen() from a worker, a 'listening' event is automatically assigned to the server instance. When the server is listening a message is send to the master where the 'listening' event is emitted.

cluster.on('listening', function (worker) {
  console.log("We are now connected");
});

Event: 'death'

  • worker {Worker object}

When any of the workers die the cluster module will emit the 'death' event. This can be used to restart the worker by calling fork() again.

cluster.on('death', function(worker) {
  console.log('worker ' + worker.pid + ' died. restart...');
  cluster.fork();
});

Event: 'setup'

  • worker {Worker object}

When the .setupMaster() function has been executed this event emits. If .setupMaster() was not executed before fork() this function will call .setupMaster() with no arguments.

cluster.setupMaster([settings])

  • settings {Object}
    • exec {String} file path to worker file. (Default=__filename)
    • args {Array} string arguments passed to worker. (Default=process.argv.slice(2))
    • silent {Boolean} whether or not to send output to parent's stdio. (Default=false)

The setupMaster is used to change the default 'fork' behavior. It takes one option object argument.

Example:

var cluster = require("cluster");
cluster.setupMaster({
  exec : "worker.js",
  args : ["--use", "https"],
  silent : true
});
cluster.autoFork();

cluster.fork([env])

  • env {Object} Key/value pairs to add to child process environment.
  • return {Worker object}

Spawn a new worker process. This can only be called from the master process.

cluster.settings

  • {Object}
    • exec {String} file path to worker file. Default: __filename
    • args {Array} string arguments passed to worker. (Default=process.argv.slice(2))
    • silent {Boolean} whether or not to send output to parent's stdio. (Default=false)

All settings set by the .setupMaster is stored in this settings object. This object is not supposed to be change or set manually.

cluster.workers

  • {Object}

In the cluster all living worker objects are stored in this object by there uniqueID as the key. This makes it easy to loop through all living workers.

// Go through all workers
function eachWorker(callback) {
  for (var uniqueID in cluster.workers) {
    callback(cluster.workers[uniqueID]);
  }
}
eachWorker(function (worker) {
  worker.send('big announcement to all workers');
});

Should you wish to reference a worker over a communication channel, using the worker's uniqueID is the easiest way to find the worker.

socket.on('data', function (uniqueID) {
  var worker = cluster.workers[uniqueID];
});

Class: Worker

A Worker object contains all public information and method about a worker. In the master it can be obtained using cluster.workers. In a worker it can be obtained using cluster.worker.

worker.uniqueID

  • {String}

Each new worker is given its own unique id, this id is stored in the uniqueID.

While a worker is alive, this is the key that indexes it in cluster.workers

worker.process

  • {ChildProcess object}

All workers are created using child_process.fork(), the returned object from this function is stored in process.

See: Child Process module

worker.suicide

  • {Boolean}

This property is a boolean. It is set when a worker dies, until then it is undefined. It is true if the worker was killed using the .destroy() method, and false otherwise.

worker.send(message, [sendHandle])

  • message {Object}
  • sendHandle {Handle object}

This function is equal to the send methods provided by child_process.fork(). In the master you should use this function to send a message to a specific worker. However in a worker you can also use process.send(message), since this is the same function.

This example will echo back all messages from the master:

if (cluster.isMaster) {
  var worker = cluster.fork();
  worker.send('hi there');

} else if (cluster.isWorker) {
  process.on('message', function (msg) {
    process.send(msg);
  });
}

worker.destroy()

This function will kill the worker, and inform the master to not spawn a new worker. To know the difference between suicide and accidentally death a suicide boolean is set to true.

cluster.on('death', function (worker) {
  if (worker.suicide === true) {
    console.log('Oh, it was just suicide\'  no need to worry').
  }
});

// destroy worker
worker.destroy();

Event: 'message'

  • message {Object}

This event is the same as the one provided by child_process.fork(). In the master you should use this event, however in a worker you can also use process.on('message')

As an example, here is a cluster that keeps count of the number of requests in the master process using the message system:

var cluster = require('cluster');
var http = require('http');

if (cluster.isMaster) {

  // Keep track of http requests
  var numReqs = 0;
  setInterval(function() {
    console.log("numReqs =", numReqs);
  }, 1000);

  // Count requestes
  var messageHandler = function (msg) {
    if (msg.cmd && msg.cmd == 'notifyRequest') {
      numReqs += 1;
    }
  };

  // Start workers and listen for messages containing notifyRequest
  cluster.autoFork();
  Object.keys(cluster.workers).forEach(function (uniqueID) {
    cluster.workers[uniqueID].on('message', messageHandler);
  });

} else {

  // Worker processes have a http server.
  http.Server(function(req, res) {
    res.writeHead(200);
    res.end("hello world\n");

    // notify master about the request
    process.send({ cmd: 'notifyRequest' });
  }).listen(8000);
}

Event: 'online'

  • worker {Worker object}

Same as the cluster.on('online') event, but emits only when the state change on the specified worker.

cluster.fork().on('online', function (worker) {
  // Worker is online
};

Event: 'listening'

  • worker {Worker object}

Same as the cluster.on('listening') event, but emits only when the state change on the specified worker.

cluster.fork().on('listening', function (worker) {
  // Worker is listening
};

Event: 'death'

  • worker {Worker object}

Same as the cluster.on('death') event, but emits only when the state change on the specified worker.

cluster.fork().on('death', function (worker) {
  // Worker has died
};