mirror of
https://github.com/nodejs/node.git
synced 2024-11-29 23:16:30 +01:00
1d5b6f26fe
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
355 lines
9.6 KiB
Markdown
355 lines
9.6 KiB
Markdown
# 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](child_process.html)
|
||
|
||
### 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
|
||
};
|