917 lines
59 KiB
HTML
917 lines
59 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width">
|
||
<meta name="nodejs.org:node-version" content="v12.22.12">
|
||
<title>Cluster | Node.js v12.22.12 Documentation</title>
|
||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:400,700,400italic&display=fallback">
|
||
<link rel="stylesheet" href="assets/style.css">
|
||
<link rel="stylesheet" href="assets/hljs.css">
|
||
<link rel="canonical" href="https://nodejs.org/api/cluster.html">
|
||
</head>
|
||
<body class="alt apidoc" id="api-section-cluster">
|
||
<div id="content" class="clearfix">
|
||
<div id="column2" class="interior">
|
||
<div id="intro" class="interior">
|
||
<a href="/" title="Go back to the home page">
|
||
Node.js
|
||
</a>
|
||
</div>
|
||
<ul>
|
||
<li><a href="documentation.html" class="nav-documentation">About this documentation</a></li>
|
||
<li><a href="synopsis.html" class="nav-synopsis">Usage and example</a></li>
|
||
</ul>
|
||
<hr class="line">
|
||
<ul>
|
||
<li><a href="assert.html" class="nav-assert">Assertion testing</a></li>
|
||
<li><a href="async_hooks.html" class="nav-async_hooks">Async hooks</a></li>
|
||
<li><a href="buffer.html" class="nav-buffer">Buffer</a></li>
|
||
<li><a href="addons.html" class="nav-addons">C++ Addons</a></li>
|
||
<li><a href="n-api.html" class="nav-n-api">C/C++ Addons with N-API</a></li>
|
||
<li><a href="embedding.html" class="nav-embedding">C++ Embedder API</a></li>
|
||
<li><a href="child_process.html" class="nav-child_process">Child Processes</a></li>
|
||
<li><a href="cluster.html" class="nav-cluster active">Cluster</a></li>
|
||
<li><a href="cli.html" class="nav-cli">Command line options</a></li>
|
||
<li><a href="console.html" class="nav-console">Console</a></li>
|
||
<li><a href="crypto.html" class="nav-crypto">Crypto</a></li>
|
||
<li><a href="debugger.html" class="nav-debugger">Debugger</a></li>
|
||
<li><a href="deprecations.html" class="nav-deprecations">Deprecated APIs</a></li>
|
||
<li><a href="dns.html" class="nav-dns">DNS</a></li>
|
||
<li><a href="domain.html" class="nav-domain">Domain</a></li>
|
||
<li><a href="errors.html" class="nav-errors">Errors</a></li>
|
||
<li><a href="events.html" class="nav-events">Events</a></li>
|
||
<li><a href="fs.html" class="nav-fs">File system</a></li>
|
||
<li><a href="globals.html" class="nav-globals">Globals</a></li>
|
||
<li><a href="http.html" class="nav-http">HTTP</a></li>
|
||
<li><a href="http2.html" class="nav-http2">HTTP/2</a></li>
|
||
<li><a href="https.html" class="nav-https">HTTPS</a></li>
|
||
<li><a href="inspector.html" class="nav-inspector">Inspector</a></li>
|
||
<li><a href="intl.html" class="nav-intl">Internationalization</a></li>
|
||
<li><a href="modules.html" class="nav-modules">Modules: CommonJS modules</a></li>
|
||
<li><a href="esm.html" class="nav-esm">Modules: ECMAScript modules</a></li>
|
||
<li><a href="module.html" class="nav-module">Modules: <code>module</code> API</a></li>
|
||
<li><a href="packages.html" class="nav-packages">Modules: Packages</a></li>
|
||
<li><a href="net.html" class="nav-net">Net</a></li>
|
||
<li><a href="os.html" class="nav-os">OS</a></li>
|
||
<li><a href="path.html" class="nav-path">Path</a></li>
|
||
<li><a href="perf_hooks.html" class="nav-perf_hooks">Performance hooks</a></li>
|
||
<li><a href="policy.html" class="nav-policy">Policies</a></li>
|
||
<li><a href="process.html" class="nav-process">Process</a></li>
|
||
<li><a href="punycode.html" class="nav-punycode">Punycode</a></li>
|
||
<li><a href="querystring.html" class="nav-querystring">Query strings</a></li>
|
||
<li><a href="readline.html" class="nav-readline">Readline</a></li>
|
||
<li><a href="repl.html" class="nav-repl">REPL</a></li>
|
||
<li><a href="report.html" class="nav-report">Report</a></li>
|
||
<li><a href="stream.html" class="nav-stream">Stream</a></li>
|
||
<li><a href="string_decoder.html" class="nav-string_decoder">String decoder</a></li>
|
||
<li><a href="timers.html" class="nav-timers">Timers</a></li>
|
||
<li><a href="tls.html" class="nav-tls">TLS/SSL</a></li>
|
||
<li><a href="tracing.html" class="nav-tracing">Trace events</a></li>
|
||
<li><a href="tty.html" class="nav-tty">TTY</a></li>
|
||
<li><a href="dgram.html" class="nav-dgram">UDP/datagram</a></li>
|
||
<li><a href="url.html" class="nav-url">URL</a></li>
|
||
<li><a href="util.html" class="nav-util">Utilities</a></li>
|
||
<li><a href="v8.html" class="nav-v8">V8</a></li>
|
||
<li><a href="vm.html" class="nav-vm">VM</a></li>
|
||
<li><a href="wasi.html" class="nav-wasi">WASI</a></li>
|
||
<li><a href="worker_threads.html" class="nav-worker_threads">Worker threads</a></li>
|
||
<li><a href="zlib.html" class="nav-zlib">Zlib</a></li>
|
||
</ul>
|
||
<hr class="line">
|
||
<ul>
|
||
<li><a href="https://github.com/nodejs/node" class="nav-https-github-com-nodejs-node">Code repository and issue tracker</a></li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div id="column1" data-id="cluster" class="interior">
|
||
<header>
|
||
<h1>Node.js v12.22.12 Documentation</h1>
|
||
<div id="gtoc">
|
||
<ul>
|
||
<li>
|
||
<a href="index.html">Index</a>
|
||
</li>
|
||
<li>
|
||
<a href="all.html">View on single page</a>
|
||
</li>
|
||
<li>
|
||
<a href="cluster.json">View as JSON</a>
|
||
</li>
|
||
|
||
<li class="version-picker">
|
||
<a href="#">View another version <span>▼</span></a>
|
||
<ol class="version-picker"><li><a href="https://nodejs.org/docs/latest-v17.x/api/cluster.html">17.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v16.x/api/cluster.html">16.x <b>LTS</b></a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v15.x/api/cluster.html">15.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v14.x/api/cluster.html">14.x <b>LTS</b></a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v13.x/api/cluster.html">13.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v12.x/api/cluster.html">12.x <b>LTS</b></a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v11.x/api/cluster.html">11.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v10.x/api/cluster.html">10.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v9.x/api/cluster.html">9.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v8.x/api/cluster.html">8.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v7.x/api/cluster.html">7.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v6.x/api/cluster.html">6.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v5.x/api/cluster.html">5.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v4.x/api/cluster.html">4.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v0.12.x/api/cluster.html">0.12.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v0.10.x/api/cluster.html">0.10.x</a></li></ol>
|
||
</li>
|
||
|
||
<li class="edit_on_github"><a href="https://github.com/nodejs/node/edit/master/doc/api/cluster.md"><span class="github_icon"><svg height="16" width="16" viewBox="0 0 16.1 16.1" fill="currentColor"><path d="M8 0a8 8 0 0 0-2.5 15.6c.4 0 .5-.2.5-.4v-1.5c-2 .4-2.5-.5-2.7-1 0-.1-.5-.9-.8-1-.3-.2-.7-.6 0-.6.6 0 1 .6 1.2.8.7 1.2 1.9 1 2.4.7 0-.5.2-.9.5-1-1.8-.3-3.7-1-3.7-4 0-.9.3-1.6.8-2.2 0-.2-.3-1 .1-2 0 0 .7-.3 2.2.7a7.4 7.4 0 0 1 4 0c1.5-1 2.2-.8 2.2-.8.5 1.1.2 2 .1 2.1.5.6.8 1.3.8 2.2 0 3-1.9 3.7-3.6 4 .3.2.5.7.5 1.4v2.2c0 .2.1.5.5.4A8 8 0 0 0 16 8a8 8 0 0 0-8-8z"/></svg></span>Edit on GitHub</a></li>
|
||
</ul>
|
||
</div>
|
||
<hr>
|
||
</header>
|
||
|
||
<div id="toc">
|
||
<h2>Table of Contents</h2>
|
||
<ul>
|
||
<li><span class="stability_2"><a href="#cluster_cluster">Cluster</a></span>
|
||
<ul>
|
||
<li><a href="#cluster_how_it_works">How it works</a></li>
|
||
<li><a href="#cluster_class_worker">Class: <code>Worker</code></a>
|
||
<ul>
|
||
<li><a href="#cluster_event_disconnect">Event: <code>'disconnect'</code></a></li>
|
||
<li><a href="#cluster_event_error">Event: <code>'error'</code></a></li>
|
||
<li><a href="#cluster_event_exit">Event: <code>'exit'</code></a></li>
|
||
<li><a href="#cluster_event_listening">Event: <code>'listening'</code></a></li>
|
||
<li><a href="#cluster_event_message">Event: <code>'message'</code></a></li>
|
||
<li><a href="#cluster_event_online">Event: <code>'online'</code></a></li>
|
||
<li><a href="#cluster_worker_disconnect"><code>worker.disconnect()</code></a></li>
|
||
<li><a href="#cluster_worker_exitedafterdisconnect"><code>worker.exitedAfterDisconnect</code></a></li>
|
||
<li><a href="#cluster_worker_id"><code>worker.id</code></a></li>
|
||
<li><a href="#cluster_worker_isconnected"><code>worker.isConnected()</code></a></li>
|
||
<li><a href="#cluster_worker_isdead"><code>worker.isDead()</code></a></li>
|
||
<li><a href="#cluster_worker_kill_signal"><code>worker.kill([signal])</code></a></li>
|
||
<li><a href="#cluster_worker_process"><code>worker.process</code></a></li>
|
||
<li><a href="#cluster_worker_send_message_sendhandle_options_callback"><code>worker.send(message[, sendHandle[, options]][, callback])</code></a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#cluster_event_disconnect_1">Event: <code>'disconnect'</code></a></li>
|
||
<li><a href="#cluster_event_exit_1">Event: <code>'exit'</code></a></li>
|
||
<li><a href="#cluster_event_fork">Event: <code>'fork'</code></a></li>
|
||
<li><a href="#cluster_event_listening_1">Event: <code>'listening'</code></a></li>
|
||
<li><a href="#cluster_event_message_1">Event: <code>'message'</code></a></li>
|
||
<li><a href="#cluster_event_online_1">Event: <code>'online'</code></a></li>
|
||
<li><a href="#cluster_event_setup">Event: <code>'setup'</code></a></li>
|
||
<li><a href="#cluster_cluster_disconnect_callback"><code>cluster.disconnect([callback])</code></a></li>
|
||
<li><a href="#cluster_cluster_fork_env"><code>cluster.fork([env])</code></a></li>
|
||
<li><a href="#cluster_cluster_ismaster"><code>cluster.isMaster</code></a></li>
|
||
<li><a href="#cluster_cluster_isworker"><code>cluster.isWorker</code></a></li>
|
||
<li><a href="#cluster_cluster_schedulingpolicy"><code>cluster.schedulingPolicy</code></a></li>
|
||
<li><a href="#cluster_cluster_settings"><code>cluster.settings</code></a></li>
|
||
<li><a href="#cluster_cluster_setupmaster_settings"><code>cluster.setupMaster([settings])</code></a></li>
|
||
<li><a href="#cluster_cluster_worker"><code>cluster.worker</code></a></li>
|
||
<li><a href="#cluster_cluster_workers"><code>cluster.workers</code></a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div id="apicontent">
|
||
<h1>Cluster<span><a class="mark" href="#cluster_cluster" id="cluster_cluster">#</a></span></h1>
|
||
|
||
<p></p><div class="api_stability api_stability_2"><a href="documentation.html#documentation_stability_index">Stability: 2</a> - Stable</div><p></p>
|
||
<p><strong>Source Code:</strong> <a href="https://github.com/nodejs/node/blob/v12.22.12/lib/cluster.js">lib/cluster.js</a></p>
|
||
<p>A single instance of Node.js runs in a single thread. To take advantage of
|
||
multi-core systems, the user will sometimes want to launch a cluster of Node.js
|
||
processes to handle the load.</p>
|
||
<p>The cluster module allows easy creation of child processes that all share
|
||
server ports.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> cluster = <span class="hljs-built_in">require</span>(<span class="hljs-string">'cluster'</span>);
|
||
<span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>);
|
||
<span class="hljs-keyword">const</span> numCPUs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'os'</span>).cpus().length;
|
||
|
||
<span class="hljs-keyword">if</span> (cluster.isMaster) {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Master <span class="hljs-subst">${process.pid}</span> is running`</span>);
|
||
|
||
<span class="hljs-comment">// Fork workers.</span>
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i < numCPUs; i++) {
|
||
cluster.fork();
|
||
}
|
||
|
||
cluster.on(<span class="hljs-string">'exit'</span>, <span class="hljs-function">(<span class="hljs-params">worker, code, signal</span>) =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`worker <span class="hljs-subst">${worker.process.pid}</span> died`</span>);
|
||
});
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-comment">// Workers can share any TCP connection</span>
|
||
<span class="hljs-comment">// In this case it is an HTTP server</span>
|
||
http.createServer(<span class="hljs-function">(<span class="hljs-params">req, res</span>) =></span> {
|
||
res.writeHead(<span class="hljs-number">200</span>);
|
||
res.end(<span class="hljs-string">'hello world\n'</span>);
|
||
}).listen(<span class="hljs-number">8000</span>);
|
||
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Worker <span class="hljs-subst">${process.pid}</span> started`</span>);
|
||
}</code></pre>
|
||
<p>Running Node.js will now share port 8000 between the workers:</p>
|
||
<pre><code class="language-console"><span class="hljs-meta">$</span><span class="bash"> node server.js</span>
|
||
Master 3596 is running
|
||
Worker 4324 started
|
||
Worker 4520 started
|
||
Worker 6056 started
|
||
Worker 5644 started</code></pre>
|
||
<p>On Windows, it is not yet possible to set up a named pipe server in a worker.</p>
|
||
<h2>How it works<span><a class="mark" href="#cluster_how_it_works" id="cluster_how_it_works">#</a></span></h2>
|
||
|
||
<p>The worker processes are spawned using the <a href="child_process.html#child_process_child_process_fork_modulepath_args_options"><code>child_process.fork()</code></a> method,
|
||
so that they can communicate with the parent via IPC and pass server
|
||
handles back and forth.</p>
|
||
<p>The cluster module supports two methods of distributing incoming
|
||
connections.</p>
|
||
<p>The first one (and the default one on all platforms except Windows),
|
||
is the round-robin approach, where the master process listens on a
|
||
port, accepts new connections and distributes them across the workers
|
||
in a round-robin fashion, with some built-in smarts to avoid
|
||
overloading a worker process.</p>
|
||
<p>The second approach is where the master process creates the listen
|
||
socket and sends it to interested workers. The workers then accept
|
||
incoming connections directly.</p>
|
||
<p>The second approach should, in theory, give the best performance.
|
||
In practice however, distribution tends to be very unbalanced due
|
||
to operating system scheduler vagaries. Loads have been observed
|
||
where over 70% of all connections ended up in just two processes,
|
||
out of a total of eight.</p>
|
||
<p>Because <code>server.listen()</code> hands off most of the work to the master
|
||
process, there are three cases where the behavior between a normal
|
||
Node.js process and a cluster worker differs:</p>
|
||
<ol>
|
||
<li><code>server.listen({fd: 7})</code> Because the message is passed to the master,
|
||
file descriptor 7 <strong>in the parent</strong> will be listened on, and the
|
||
handle passed to the worker, rather than listening to the worker's
|
||
idea of what the number 7 file descriptor references.</li>
|
||
<li><code>server.listen(handle)</code> Listening on handles explicitly will cause
|
||
the worker to use the supplied handle, rather than talk to the master
|
||
process.</li>
|
||
<li><code>server.listen(0)</code> Normally, this will cause servers to listen on a
|
||
random port. However, in a cluster, each worker will receive the
|
||
same "random" port each time they do <code>listen(0)</code>. In essence, the
|
||
port is random the first time, but predictable thereafter. To listen
|
||
on a unique port, generate a port number based on the cluster worker ID.</li>
|
||
</ol>
|
||
<p>Node.js does not provide routing logic. It is, therefore important to design an
|
||
application such that it does not rely too heavily on in-memory data objects for
|
||
things like sessions and login.</p>
|
||
<p>Because workers are all separate processes, they can be killed or
|
||
re-spawned depending on a program's needs, without affecting other
|
||
workers. As long as there are some workers still alive, the server will
|
||
continue to accept connections. If no workers are alive, existing connections
|
||
will be dropped and new connections will be refused. Node.js does not
|
||
automatically manage the number of workers, however. It is the application's
|
||
responsibility to manage the worker pool based on its own needs.</p>
|
||
<p>Although a primary use case for the <code>cluster</code> module is networking, it can
|
||
also be used for other use cases requiring worker processes.</p>
|
||
<h2>Class: <code>Worker</code><span><a class="mark" href="#cluster_class_worker" id="cluster_class_worker">#</a></span></h2>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.7.0</span>
|
||
</div>
|
||
<ul>
|
||
<li>Extends: <a href="events.html#events_class_eventemitter" class="type"><EventEmitter></a></li>
|
||
</ul>
|
||
<p>A <code>Worker</code> object contains all public information and method about a worker.
|
||
In the master it can be obtained using <code>cluster.workers</code>. In a worker
|
||
it can be obtained using <code>cluster.worker</code>.</p>
|
||
<h3>Event: <code>'disconnect'</code><span><a class="mark" href="#cluster_event_disconnect" id="cluster_event_disconnect">#</a></span></h3>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.7.7</span>
|
||
</div>
|
||
<p>Similar to the <code>cluster.on('disconnect')</code> event, but specific to this worker.</p>
|
||
<pre><code class="language-js">cluster.fork().on(<span class="hljs-string">'disconnect'</span>, <span class="hljs-function">() =></span> {
|
||
<span class="hljs-comment">// Worker has disconnected</span>
|
||
});</code></pre>
|
||
<h3>Event: <code>'error'</code><span><a class="mark" href="#cluster_event_error" id="cluster_event_error">#</a></span></h3>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.7.3</span>
|
||
</div>
|
||
<p>This event is the same as the one provided by <a href="child_process.html#child_process_child_process_fork_modulepath_args_options"><code>child_process.fork()</code></a>.</p>
|
||
<p>Within a worker, <code>process.on('error')</code> may also be used.</p>
|
||
<h3>Event: <code>'exit'</code><span><a class="mark" href="#cluster_event_exit" id="cluster_event_exit">#</a></span></h3>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.11.2</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>code</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type" class="type"><number></a> The exit code, if it exited normally.</li>
|
||
<li><code>signal</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> The name of the signal (e.g. <code>'SIGHUP'</code>) that caused
|
||
the process to be killed.</li>
|
||
</ul>
|
||
<p>Similar to the <code>cluster.on('exit')</code> event, but specific to this worker.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> worker = cluster.fork();
|
||
worker.on(<span class="hljs-string">'exit'</span>, <span class="hljs-function">(<span class="hljs-params">code, signal</span>) =></span> {
|
||
<span class="hljs-keyword">if</span> (signal) {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`worker was killed by signal: <span class="hljs-subst">${signal}</span>`</span>);
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (code !== <span class="hljs-number">0</span>) {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`worker exited with error code: <span class="hljs-subst">${code}</span>`</span>);
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'worker success!'</span>);
|
||
}
|
||
});</code></pre>
|
||
<h3>Event: <code>'listening'</code><span><a class="mark" href="#cluster_event_listening" id="cluster_event_listening">#</a></span></h3>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.7.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>address</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a></li>
|
||
</ul>
|
||
<p>Similar to the <code>cluster.on('listening')</code> event, but specific to this worker.</p>
|
||
<pre><code class="language-js">cluster.fork().on(<span class="hljs-string">'listening'</span>, <span class="hljs-function">(<span class="hljs-params">address</span>) =></span> {
|
||
<span class="hljs-comment">// Worker is listening</span>
|
||
});</code></pre>
|
||
<p>It is not emitted in the worker.</p>
|
||
<h3>Event: <code>'message'</code><span><a class="mark" href="#cluster_event_message" id="cluster_event_message">#</a></span></h3>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.7.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>message</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a></li>
|
||
<li><code>handle</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Undefined_type" class="type"><undefined></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a></li>
|
||
</ul>
|
||
<p>Similar to the <code>'message'</code> event of <code>cluster</code>, but specific to this worker.</p>
|
||
<p>Within a worker, <code>process.on('message')</code> may also be used.</p>
|
||
<p>See <a href="process.html#process_event_message"><code>process</code> event: <code>'message'</code></a>.</p>
|
||
<p>Here is an example using the message system. It keeps a count in the master
|
||
process of the number of HTTP requests received by the workers:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> cluster = <span class="hljs-built_in">require</span>(<span class="hljs-string">'cluster'</span>);
|
||
<span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>);
|
||
|
||
<span class="hljs-keyword">if</span> (cluster.isMaster) {
|
||
|
||
<span class="hljs-comment">// Keep track of http requests</span>
|
||
<span class="hljs-keyword">let</span> numReqs = <span class="hljs-number">0</span>;
|
||
<span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`numReqs = <span class="hljs-subst">${numReqs}</span>`</span>);
|
||
}, <span class="hljs-number">1000</span>);
|
||
|
||
<span class="hljs-comment">// Count requests</span>
|
||
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">messageHandler</span>(<span class="hljs-params">msg</span>) </span>{
|
||
<span class="hljs-keyword">if</span> (msg.cmd && msg.cmd === <span class="hljs-string">'notifyRequest'</span>) {
|
||
numReqs += <span class="hljs-number">1</span>;
|
||
}
|
||
}
|
||
|
||
<span class="hljs-comment">// Start workers and listen for messages containing notifyRequest</span>
|
||
<span class="hljs-keyword">const</span> numCPUs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'os'</span>).cpus().length;
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i < numCPUs; i++) {
|
||
cluster.fork();
|
||
}
|
||
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> id <span class="hljs-keyword">in</span> cluster.workers) {
|
||
cluster.workers[id].on(<span class="hljs-string">'message'</span>, messageHandler);
|
||
}
|
||
|
||
} <span class="hljs-keyword">else</span> {
|
||
|
||
<span class="hljs-comment">// Worker processes have a http server.</span>
|
||
http.Server(<span class="hljs-function">(<span class="hljs-params">req, res</span>) =></span> {
|
||
res.writeHead(<span class="hljs-number">200</span>);
|
||
res.end(<span class="hljs-string">'hello world\n'</span>);
|
||
|
||
<span class="hljs-comment">// Notify master about the request</span>
|
||
process.send({ <span class="hljs-attr">cmd</span>: <span class="hljs-string">'notifyRequest'</span> });
|
||
}).listen(<span class="hljs-number">8000</span>);
|
||
}</code></pre>
|
||
<h3>Event: <code>'online'</code><span><a class="mark" href="#cluster_event_online" id="cluster_event_online">#</a></span></h3>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.7.0</span>
|
||
</div>
|
||
<p>Similar to the <code>cluster.on('online')</code> event, but specific to this worker.</p>
|
||
<pre><code class="language-js">cluster.fork().on(<span class="hljs-string">'online'</span>, <span class="hljs-function">() =></span> {
|
||
<span class="hljs-comment">// Worker is online</span>
|
||
});</code></pre>
|
||
<p>It is not emitted in the worker.</p>
|
||
<h3><code>worker.disconnect()</code><span><a class="mark" href="#cluster_worker_disconnect" id="cluster_worker_disconnect">#</a></span></h3>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v7.3.0</td>
|
||
<td><p>This method now returns a reference to <code>worker</code>.</p></td></tr>
|
||
<tr><td>v0.7.7</td>
|
||
<td><p><span>Added in: v0.7.7</span></p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<ul>
|
||
<li>Returns: <a href="cluster.html#cluster_class_worker" class="type"><cluster.Worker></a> A reference to <code>worker</code>.</li>
|
||
</ul>
|
||
<p>In a worker, this function will close all servers, wait for the <code>'close'</code> event
|
||
on those servers, and then disconnect the IPC channel.</p>
|
||
<p>In the master, an internal message is sent to the worker causing it to call
|
||
<code>.disconnect()</code> on itself.</p>
|
||
<p>Causes <code>.exitedAfterDisconnect</code> to be set.</p>
|
||
<p>After a server is closed, it will no longer accept new connections,
|
||
but connections may be accepted by any other listening worker. Existing
|
||
connections will be allowed to close as usual. When no more connections exist,
|
||
see <a href="net.html#net_event_close"><code>server.close()</code></a>, the IPC channel to the worker will close allowing it
|
||
to die gracefully.</p>
|
||
<p>The above applies <em>only</em> to server connections, client connections are not
|
||
automatically closed by workers, and disconnect does not wait for them to close
|
||
before exiting.</p>
|
||
<p>In a worker, <code>process.disconnect</code> exists, but it is not this function;
|
||
it is <a href="child_process.html#child_process_subprocess_disconnect"><code>disconnect()</code></a>.</p>
|
||
<p>Because long living server connections may block workers from disconnecting, it
|
||
may be useful to send a message, so application specific actions may be taken to
|
||
close them. It also may be useful to implement a timeout, killing a worker if
|
||
the <code>'disconnect'</code> event has not been emitted after some time.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">if</span> (cluster.isMaster) {
|
||
<span class="hljs-keyword">const</span> worker = cluster.fork();
|
||
<span class="hljs-keyword">let</span> timeout;
|
||
|
||
worker.on(<span class="hljs-string">'listening'</span>, <span class="hljs-function">(<span class="hljs-params">address</span>) =></span> {
|
||
worker.send(<span class="hljs-string">'shutdown'</span>);
|
||
worker.disconnect();
|
||
timeout = <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =></span> {
|
||
worker.kill();
|
||
}, <span class="hljs-number">2000</span>);
|
||
});
|
||
|
||
worker.on(<span class="hljs-string">'disconnect'</span>, <span class="hljs-function">() =></span> {
|
||
<span class="hljs-built_in">clearTimeout</span>(timeout);
|
||
});
|
||
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (cluster.isWorker) {
|
||
<span class="hljs-keyword">const</span> net = <span class="hljs-built_in">require</span>(<span class="hljs-string">'net'</span>);
|
||
<span class="hljs-keyword">const</span> server = net.createServer(<span class="hljs-function">(<span class="hljs-params">socket</span>) =></span> {
|
||
<span class="hljs-comment">// Connections never end</span>
|
||
});
|
||
|
||
server.listen(<span class="hljs-number">8000</span>);
|
||
|
||
process.on(<span class="hljs-string">'message'</span>, <span class="hljs-function">(<span class="hljs-params">msg</span>) =></span> {
|
||
<span class="hljs-keyword">if</span> (msg === <span class="hljs-string">'shutdown'</span>) {
|
||
<span class="hljs-comment">// Initiate graceful close of any connections to server</span>
|
||
}
|
||
});
|
||
}</code></pre>
|
||
<h3><code>worker.exitedAfterDisconnect</code><span><a class="mark" href="#cluster_worker_exitedafterdisconnect" id="cluster_worker_exitedafterdisconnect">#</a></span></h3>
|
||
<div class="api_metadata">
|
||
<span>Added in: v6.0.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a></li>
|
||
</ul>
|
||
<p>This property is <code>true</code> if the worker exited due to <code>.kill()</code> or
|
||
<code>.disconnect()</code>. If the worker exited any other way, it is <code>false</code>. If the
|
||
worker has not exited, it is <code>undefined</code>.</p>
|
||
<p>The boolean <a href="#cluster_worker_exitedafterdisconnect"><code>worker.exitedAfterDisconnect</code></a> allows distinguishing between
|
||
voluntary and accidental exit, the master may choose not to respawn a worker
|
||
based on this value.</p>
|
||
<pre><code class="language-js">cluster.on(<span class="hljs-string">'exit'</span>, <span class="hljs-function">(<span class="hljs-params">worker, code, signal</span>) =></span> {
|
||
<span class="hljs-keyword">if</span> (worker.exitedAfterDisconnect === <span class="hljs-literal">true</span>) {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Oh, it was just voluntary – no need to worry'</span>);
|
||
}
|
||
});
|
||
|
||
<span class="hljs-comment">// kill worker</span>
|
||
worker.kill();</code></pre>
|
||
<h3><code>worker.id</code><span><a class="mark" href="#cluster_worker_id" id="cluster_worker_id">#</a></span></h3>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.8.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type" class="type"><number></a></li>
|
||
</ul>
|
||
<p>Each new worker is given its own unique id, this id is stored in the
|
||
<code>id</code>.</p>
|
||
<p>While a worker is alive, this is the key that indexes it in
|
||
<code>cluster.workers</code>.</p>
|
||
<h3><code>worker.isConnected()</code><span><a class="mark" href="#cluster_worker_isconnected" id="cluster_worker_isconnected">#</a></span></h3>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.11.14</span>
|
||
</div>
|
||
<p>This function returns <code>true</code> if the worker is connected to its master via its
|
||
IPC channel, <code>false</code> otherwise. A worker is connected to its master after it
|
||
has been created. It is disconnected after the <code>'disconnect'</code> event is emitted.</p>
|
||
<h3><code>worker.isDead()</code><span><a class="mark" href="#cluster_worker_isdead" id="cluster_worker_isdead">#</a></span></h3>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.11.14</span>
|
||
</div>
|
||
<p>This function returns <code>true</code> if the worker's process has terminated (either
|
||
because of exiting or being signaled). Otherwise, it returns <code>false</code>.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> cluster = <span class="hljs-built_in">require</span>(<span class="hljs-string">'cluster'</span>);
|
||
<span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>);
|
||
<span class="hljs-keyword">const</span> numCPUs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'os'</span>).cpus().length;
|
||
|
||
<span class="hljs-keyword">if</span> (cluster.isMaster) {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Master <span class="hljs-subst">${process.pid}</span> is running`</span>);
|
||
|
||
<span class="hljs-comment">// Fork workers.</span>
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i < numCPUs; i++) {
|
||
cluster.fork();
|
||
}
|
||
|
||
cluster.on(<span class="hljs-string">'fork'</span>, <span class="hljs-function">(<span class="hljs-params">worker</span>) =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'worker is dead:'</span>, worker.isDead());
|
||
});
|
||
|
||
cluster.on(<span class="hljs-string">'exit'</span>, <span class="hljs-function">(<span class="hljs-params">worker, code, signal</span>) =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'worker is dead:'</span>, worker.isDead());
|
||
});
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-comment">// Workers can share any TCP connection. In this case, it is an HTTP server.</span>
|
||
http.createServer(<span class="hljs-function">(<span class="hljs-params">req, res</span>) =></span> {
|
||
res.writeHead(<span class="hljs-number">200</span>);
|
||
res.end(<span class="hljs-string">`Current process\n <span class="hljs-subst">${process.pid}</span>`</span>);
|
||
process.kill(process.pid);
|
||
}).listen(<span class="hljs-number">8000</span>);
|
||
}</code></pre>
|
||
<h3><code>worker.kill([signal])</code><span><a class="mark" href="#cluster_worker_kill_signal" id="cluster_worker_kill_signal">#</a></span></h3>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.12</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>signal</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> Name of the kill signal to send to the worker
|
||
process. <strong>Default</strong>: <code>'SIGTERM'</code></li>
|
||
</ul>
|
||
<p>This function will kill the worker. In the master, it does this by disconnecting
|
||
the <code>worker.process</code>, and once disconnected, killing with <code>signal</code>. In the
|
||
worker, it does it by disconnecting the channel, and then exiting with code <code>0</code>.</p>
|
||
<p>Because <code>kill()</code> attempts to gracefully disconnect the worker process, it is
|
||
susceptible to waiting indefinitely for the disconnect to complete. For example,
|
||
if the worker enters an infinite loop, a graceful disconnect will never occur.
|
||
If the graceful disconnect behavior is not needed, use <code>worker.process.kill()</code>.</p>
|
||
<p>Causes <code>.exitedAfterDisconnect</code> to be set.</p>
|
||
<p>This method is aliased as <code>worker.destroy()</code> for backward compatibility.</p>
|
||
<p>In a worker, <code>process.kill()</code> exists, but it is not this function;
|
||
it is <a href="process.html#process_process_kill_pid_signal"><code>kill()</code></a>.</p>
|
||
<h3><code>worker.process</code><span><a class="mark" href="#cluster_worker_process" id="cluster_worker_process">#</a></span></h3>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.7.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="child_process.html#child_process_class_childprocess" class="type"><ChildProcess></a></li>
|
||
</ul>
|
||
<p>All workers are created using <a href="child_process.html#child_process_child_process_fork_modulepath_args_options"><code>child_process.fork()</code></a>, the returned object
|
||
from this function is stored as <code>.process</code>. In a worker, the global <code>process</code>
|
||
is stored.</p>
|
||
<p>See: <a href="child_process.html#child_process_child_process_fork_modulepath_args_options">Child Process module</a>.</p>
|
||
<p>Workers will call <code>process.exit(0)</code> if the <code>'disconnect'</code> event occurs
|
||
on <code>process</code> and <code>.exitedAfterDisconnect</code> is not <code>true</code>. This protects against
|
||
accidental disconnection.</p>
|
||
<h3><code>worker.send(message[, sendHandle[, options]][, callback])</code><span><a class="mark" href="#cluster_worker_send_message_sendhandle_options_callback" id="cluster_worker_send_message_sendhandle_options_callback">#</a></span></h3>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v4.0.0</td>
|
||
<td><p>The <code>callback</code> parameter is supported now.</p></td></tr>
|
||
<tr><td>v0.7.0</td>
|
||
<td><p><span>Added in: v0.7.0</span></p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<ul>
|
||
<li><code>message</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a></li>
|
||
<li><code>sendHandle</code> <a href="net.html#net_server_listen_handle_backlog_callback" class="type"><Handle></a></li>
|
||
<li><code>options</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a> The <code>options</code> argument, if present, is an object used to
|
||
parameterize the sending of certain types of handles. <code>options</code> supports
|
||
the following properties:
|
||
<ul>
|
||
<li><code>keepOpen</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> A value that can be used when passing instances of
|
||
<code>net.Socket</code>. When <code>true</code>, the socket is kept open in the sending process.
|
||
<strong>Default:</strong> <code>false</code>.</li>
|
||
</ul>
|
||
</li>
|
||
<li><code>callback</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a></li>
|
||
<li>Returns: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a></li>
|
||
</ul>
|
||
<p>Send a message to a worker or master, optionally with a handle.</p>
|
||
<p>In the master this sends a message to a specific worker. It is identical to
|
||
<a href="child_process.html#child_process_subprocess_send_message_sendhandle_options_callback"><code>ChildProcess.send()</code></a>.</p>
|
||
<p>In a worker this sends a message to the master. It is identical to
|
||
<code>process.send()</code>.</p>
|
||
<p>This example will echo back all messages from the master:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">if</span> (cluster.isMaster) {
|
||
<span class="hljs-keyword">const</span> worker = cluster.fork();
|
||
worker.send(<span class="hljs-string">'hi there'</span>);
|
||
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (cluster.isWorker) {
|
||
process.on(<span class="hljs-string">'message'</span>, <span class="hljs-function">(<span class="hljs-params">msg</span>) =></span> {
|
||
process.send(msg);
|
||
});
|
||
}</code></pre>
|
||
<h2>Event: <code>'disconnect'</code><span><a class="mark" href="#cluster_event_disconnect_1" id="cluster_event_disconnect_1">#</a></span></h2>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.7.9</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>worker</code> <a href="cluster.html#cluster_class_worker" class="type"><cluster.Worker></a></li>
|
||
</ul>
|
||
<p>Emitted after the worker IPC channel has disconnected. This can occur when a
|
||
worker exits gracefully, is killed, or is disconnected manually (such as with
|
||
<code>worker.disconnect()</code>).</p>
|
||
<p>There may be a delay between the <code>'disconnect'</code> and <code>'exit'</code> events. These
|
||
events can be used to detect if the process is stuck in a cleanup or if there
|
||
are long-living connections.</p>
|
||
<pre><code class="language-js">cluster.on(<span class="hljs-string">'disconnect'</span>, <span class="hljs-function">(<span class="hljs-params">worker</span>) =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The worker #<span class="hljs-subst">${worker.id}</span> has disconnected`</span>);
|
||
});</code></pre>
|
||
<h2>Event: <code>'exit'</code><span><a class="mark" href="#cluster_event_exit_1" id="cluster_event_exit_1">#</a></span></h2>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.7.9</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>worker</code> <a href="cluster.html#cluster_class_worker" class="type"><cluster.Worker></a></li>
|
||
<li><code>code</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type" class="type"><number></a> The exit code, if it exited normally.</li>
|
||
<li><code>signal</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> The name of the signal (e.g. <code>'SIGHUP'</code>) that caused
|
||
the process to be killed.</li>
|
||
</ul>
|
||
<p>When any of the workers die the cluster module will emit the <code>'exit'</code> event.</p>
|
||
<p>This can be used to restart the worker by calling <a href="#cluster_cluster_fork_env"><code>.fork()</code></a> again.</p>
|
||
<pre><code class="language-js">cluster.on(<span class="hljs-string">'exit'</span>, <span class="hljs-function">(<span class="hljs-params">worker, code, signal</span>) =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'worker %d died (%s). restarting...'</span>,
|
||
worker.process.pid, signal || code);
|
||
cluster.fork();
|
||
});</code></pre>
|
||
<p>See <a href="child_process.html#child_process_event_exit"><code>child_process</code> event: <code>'exit'</code></a>.</p>
|
||
<h2>Event: <code>'fork'</code><span><a class="mark" href="#cluster_event_fork" id="cluster_event_fork">#</a></span></h2>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.7.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>worker</code> <a href="cluster.html#cluster_class_worker" class="type"><cluster.Worker></a></li>
|
||
</ul>
|
||
<p>When a new worker is forked the cluster module will emit a <code>'fork'</code> event.
|
||
This can be used to log worker activity, and create a custom timeout.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> timeouts = [];
|
||
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">errorMsg</span>(<span class="hljs-params"></span>) </span>{
|
||
<span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Something must be wrong with the connection ...'</span>);
|
||
}
|
||
|
||
cluster.on(<span class="hljs-string">'fork'</span>, <span class="hljs-function">(<span class="hljs-params">worker</span>) =></span> {
|
||
timeouts[worker.id] = <span class="hljs-built_in">setTimeout</span>(errorMsg, <span class="hljs-number">2000</span>);
|
||
});
|
||
cluster.on(<span class="hljs-string">'listening'</span>, <span class="hljs-function">(<span class="hljs-params">worker, address</span>) =></span> {
|
||
<span class="hljs-built_in">clearTimeout</span>(timeouts[worker.id]);
|
||
});
|
||
cluster.on(<span class="hljs-string">'exit'</span>, <span class="hljs-function">(<span class="hljs-params">worker, code, signal</span>) =></span> {
|
||
<span class="hljs-built_in">clearTimeout</span>(timeouts[worker.id]);
|
||
errorMsg();
|
||
});</code></pre>
|
||
<h2>Event: <code>'listening'</code><span><a class="mark" href="#cluster_event_listening_1" id="cluster_event_listening_1">#</a></span></h2>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.7.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>worker</code> <a href="cluster.html#cluster_class_worker" class="type"><cluster.Worker></a></li>
|
||
<li><code>address</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a></li>
|
||
</ul>
|
||
<p>After calling <code>listen()</code> from a worker, when the <code>'listening'</code> event is emitted
|
||
on the server a <code>'listening'</code> event will also be emitted on <code>cluster</code> in the
|
||
master.</p>
|
||
<p>The event handler is executed with two arguments, the <code>worker</code> contains the
|
||
worker object and the <code>address</code> object contains the following connection
|
||
properties: <code>address</code>, <code>port</code> and <code>addressType</code>. This is very useful if the
|
||
worker is listening on more than one address.</p>
|
||
<pre><code class="language-js">cluster.on(<span class="hljs-string">'listening'</span>, <span class="hljs-function">(<span class="hljs-params">worker, address</span>) =></span> {
|
||
<span class="hljs-built_in">console</span>.log(
|
||
<span class="hljs-string">`A worker is now connected to <span class="hljs-subst">${address.address}</span>:<span class="hljs-subst">${address.port}</span>`</span>);
|
||
});</code></pre>
|
||
<p>The <code>addressType</code> is one of:</p>
|
||
<ul>
|
||
<li><code>4</code> (TCPv4)</li>
|
||
<li><code>6</code> (TCPv6)</li>
|
||
<li><code>-1</code> (Unix domain socket)</li>
|
||
<li><code>'udp4'</code> or <code>'udp6'</code> (UDP v4 or v6)</li>
|
||
</ul>
|
||
<h2>Event: <code>'message'</code><span><a class="mark" href="#cluster_event_message_1" id="cluster_event_message_1">#</a></span></h2>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v6.0.0</td>
|
||
<td><p>The <code>worker</code> parameter is passed now; see below for details.</p></td></tr>
|
||
<tr><td>v2.5.0</td>
|
||
<td><p><span>Added in: v2.5.0</span></p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<ul>
|
||
<li><code>worker</code> <a href="cluster.html#cluster_class_worker" class="type"><cluster.Worker></a></li>
|
||
<li><code>message</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a></li>
|
||
<li><code>handle</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Undefined_type" class="type"><undefined></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a></li>
|
||
</ul>
|
||
<p>Emitted when the cluster master receives a message from any worker.</p>
|
||
<p>See <a href="child_process.html#child_process_event_message"><code>child_process</code> event: <code>'message'</code></a>.</p>
|
||
<h2>Event: <code>'online'</code><span><a class="mark" href="#cluster_event_online_1" id="cluster_event_online_1">#</a></span></h2>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.7.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>worker</code> <a href="cluster.html#cluster_class_worker" class="type"><cluster.Worker></a></li>
|
||
</ul>
|
||
<p>After forking a new worker, the worker should respond with an online message.
|
||
When the master receives an online message it will emit this event.
|
||
The difference between <code>'fork'</code> and <code>'online'</code> is that fork is emitted when the
|
||
master forks a worker, and <code>'online'</code> is emitted when the worker is running.</p>
|
||
<pre><code class="language-js">cluster.on(<span class="hljs-string">'online'</span>, <span class="hljs-function">(<span class="hljs-params">worker</span>) =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Yay, the worker responded after it was forked'</span>);
|
||
});</code></pre>
|
||
<h2>Event: <code>'setup'</code><span><a class="mark" href="#cluster_event_setup" id="cluster_event_setup">#</a></span></h2>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.7.1</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>settings</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a></li>
|
||
</ul>
|
||
<p>Emitted every time <a href="#cluster_cluster_setupmaster_settings"><code>.setupMaster()</code></a> is called.</p>
|
||
<p>The <code>settings</code> object is the <code>cluster.settings</code> object at the time
|
||
<a href="#cluster_cluster_setupmaster_settings"><code>.setupMaster()</code></a> was called and is advisory only, since multiple calls to
|
||
<a href="#cluster_cluster_setupmaster_settings"><code>.setupMaster()</code></a> can be made in a single tick.</p>
|
||
<p>If accuracy is important, use <code>cluster.settings</code>.</p>
|
||
<h2><code>cluster.disconnect([callback])</code><span><a class="mark" href="#cluster_cluster_disconnect_callback" id="cluster_cluster_disconnect_callback">#</a></span></h2>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.7.7</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>callback</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> Called when all workers are disconnected and handles are
|
||
closed.</li>
|
||
</ul>
|
||
<p>Calls <code>.disconnect()</code> on each worker in <code>cluster.workers</code>.</p>
|
||
<p>When they are disconnected all internal handles will be closed, allowing the
|
||
master process to die gracefully if no other event is waiting.</p>
|
||
<p>The method takes an optional callback argument which will be called when
|
||
finished.</p>
|
||
<p>This can only be called from the master process.</p>
|
||
<h2><code>cluster.fork([env])</code><span><a class="mark" href="#cluster_cluster_fork_env" id="cluster_cluster_fork_env">#</a></span></h2>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.6.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>env</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a> Key/value pairs to add to worker process environment.</li>
|
||
<li>Returns: <a href="cluster.html#cluster_class_worker" class="type"><cluster.Worker></a></li>
|
||
</ul>
|
||
<p>Spawn a new worker process.</p>
|
||
<p>This can only be called from the master process.</p>
|
||
<h2><code>cluster.isMaster</code><span><a class="mark" href="#cluster_cluster_ismaster" id="cluster_cluster_ismaster">#</a></span></h2>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.8.1</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a></li>
|
||
</ul>
|
||
<p>True if the process is a master. This is determined
|
||
by the <code>process.env.NODE_UNIQUE_ID</code>. If <code>process.env.NODE_UNIQUE_ID</code> is
|
||
undefined, then <code>isMaster</code> is <code>true</code>.</p>
|
||
<h2><code>cluster.isWorker</code><span><a class="mark" href="#cluster_cluster_isworker" id="cluster_cluster_isworker">#</a></span></h2>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.6.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a></li>
|
||
</ul>
|
||
<p>True if the process is not a master (it is the negation of <code>cluster.isMaster</code>).</p>
|
||
<h2><code>cluster.schedulingPolicy</code><span><a class="mark" href="#cluster_cluster_schedulingpolicy" id="cluster_cluster_schedulingpolicy">#</a></span></h2>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.11.2</span>
|
||
</div>
|
||
<p>The scheduling policy, either <code>cluster.SCHED_RR</code> for round-robin or
|
||
<code>cluster.SCHED_NONE</code> to leave it to the operating system. This is a
|
||
global setting and effectively frozen once either the first worker is spawned,
|
||
or <a href="#cluster_cluster_setupmaster_settings"><code>.setupMaster()</code></a> is called, whichever comes first.</p>
|
||
<p><code>SCHED_RR</code> is the default on all operating systems except Windows.
|
||
Windows will change to <code>SCHED_RR</code> once libuv is able to effectively
|
||
distribute IOCP handles without incurring a large performance hit.</p>
|
||
<p><code>cluster.schedulingPolicy</code> can also be set through the
|
||
<code>NODE_CLUSTER_SCHED_POLICY</code> environment variable. Valid
|
||
values are <code>'rr'</code> and <code>'none'</code>.</p>
|
||
<h2><code>cluster.settings</code><span><a class="mark" href="#cluster_cluster_settings" id="cluster_cluster_settings">#</a></span></h2>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v12.16.0</td>
|
||
<td><p>The <code>serialization</code> option is supported now.</p></td></tr>
|
||
<tr><td>v9.5.0</td>
|
||
<td><p>The <code>cwd</code> option is supported now.</p></td></tr>
|
||
<tr><td>v9.4.0</td>
|
||
<td><p>The <code>windowsHide</code> option is supported now.</p></td></tr>
|
||
<tr><td>v8.2.0</td>
|
||
<td><p>The <code>inspectPort</code> option is supported now.</p></td></tr>
|
||
<tr><td>v6.4.0</td>
|
||
<td><p>The <code>stdio</code> option is supported now.</p></td></tr>
|
||
<tr><td>v0.7.1</td>
|
||
<td><p><span>Added in: v0.7.1</span></p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a>
|
||
<ul>
|
||
<li><code>execArgv</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string[]></a> List of string arguments passed to the Node.js
|
||
executable. <strong>Default:</strong> <code>process.execArgv</code>.</li>
|
||
<li><code>exec</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> File path to worker file. <strong>Default:</strong> <code>process.argv[1]</code>.</li>
|
||
<li><code>args</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string[]></a> String arguments passed to worker.
|
||
<strong>Default:</strong> <code>process.argv.slice(2)</code>.</li>
|
||
<li><code>cwd</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> Current working directory of the worker process. <strong>Default:</strong>
|
||
<code>undefined</code> (inherits from parent process).</li>
|
||
<li><code>serialization</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> Specify the kind of serialization used for sending
|
||
messages between processes. Possible values are <code>'json'</code> and <code>'advanced'</code>.
|
||
See <a href="child_process.html#child_process_advanced_serialization">Advanced serialization for <code>child_process</code></a> for more details.
|
||
<strong>Default:</strong> <code>false</code>.</li>
|
||
<li><code>silent</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> Whether or not to send output to parent's stdio.
|
||
<strong>Default:</strong> <code>false</code>.</li>
|
||
<li><code>stdio</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array" class="type"><Array></a> Configures the stdio of forked processes. Because the
|
||
cluster module relies on IPC to function, this configuration must contain an
|
||
<code>'ipc'</code> entry. When this option is provided, it overrides <code>silent</code>.</li>
|
||
<li><code>uid</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type" class="type"><number></a> Sets the user identity of the process. (See <a href="http://man7.org/linux/man-pages/man2/setuid.2.html"><code>setuid(2)</code></a>.)</li>
|
||
<li><code>gid</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type" class="type"><number></a> Sets the group identity of the process. (See <a href="http://man7.org/linux/man-pages/man2/setgid.2.html"><code>setgid(2)</code></a>.)</li>
|
||
<li><code>inspectPort</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type" class="type"><number></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> Sets inspector port of worker.
|
||
This can be a number, or a function that takes no arguments and returns a
|
||
number. By default each worker gets its own port, incremented from the
|
||
master's <code>process.debugPort</code>.</li>
|
||
<li><code>windowsHide</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> Hide the forked processes console window that would
|
||
normally be created on Windows systems. <strong>Default:</strong> <code>false</code>.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<p>After calling <a href="#cluster_cluster_setupmaster_settings"><code>.setupMaster()</code></a> (or <a href="#cluster_cluster_fork_env"><code>.fork()</code></a>) this settings object will
|
||
contain the settings, including the default values.</p>
|
||
<p>This object is not intended to be changed or set manually.</p>
|
||
<h2><code>cluster.setupMaster([settings])</code><span><a class="mark" href="#cluster_cluster_setupmaster_settings" id="cluster_cluster_setupmaster_settings">#</a></span></h2>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v6.4.0</td>
|
||
<td><p>The <code>stdio</code> option is supported now.</p></td></tr>
|
||
<tr><td>v0.7.1</td>
|
||
<td><p><span>Added in: v0.7.1</span></p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<ul>
|
||
<li><code>settings</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a> See <a href="#cluster_cluster_settings"><code>cluster.settings</code></a>.</li>
|
||
</ul>
|
||
<p><code>setupMaster</code> is used to change the default 'fork' behavior. Once called,
|
||
the settings will be present in <code>cluster.settings</code>.</p>
|
||
<p>Any settings changes only affect future calls to <a href="#cluster_cluster_fork_env"><code>.fork()</code></a> and have no
|
||
effect on workers that are already running.</p>
|
||
<p>The only attribute of a worker that cannot be set via <code>.setupMaster()</code> is
|
||
the <code>env</code> passed to <a href="#cluster_cluster_fork_env"><code>.fork()</code></a>.</p>
|
||
<p>The defaults above apply to the first call only; the defaults for later
|
||
calls are the current values at the time of <code>cluster.setupMaster()</code> is called.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> cluster = <span class="hljs-built_in">require</span>(<span class="hljs-string">'cluster'</span>);
|
||
cluster.setupMaster({
|
||
<span class="hljs-attr">exec</span>: <span class="hljs-string">'worker.js'</span>,
|
||
<span class="hljs-attr">args</span>: [<span class="hljs-string">'--use'</span>, <span class="hljs-string">'https'</span>],
|
||
<span class="hljs-attr">silent</span>: <span class="hljs-literal">true</span>
|
||
});
|
||
cluster.fork(); <span class="hljs-comment">// https worker</span>
|
||
cluster.setupMaster({
|
||
<span class="hljs-attr">exec</span>: <span class="hljs-string">'worker.js'</span>,
|
||
<span class="hljs-attr">args</span>: [<span class="hljs-string">'--use'</span>, <span class="hljs-string">'http'</span>]
|
||
});
|
||
cluster.fork(); <span class="hljs-comment">// http worker</span></code></pre>
|
||
<p>This can only be called from the master process.</p>
|
||
<h2><code>cluster.worker</code><span><a class="mark" href="#cluster_cluster_worker" id="cluster_cluster_worker">#</a></span></h2>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.7.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a></li>
|
||
</ul>
|
||
<p>A reference to the current worker object. Not available in the master process.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> cluster = <span class="hljs-built_in">require</span>(<span class="hljs-string">'cluster'</span>);
|
||
|
||
<span class="hljs-keyword">if</span> (cluster.isMaster) {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'I am master'</span>);
|
||
cluster.fork();
|
||
cluster.fork();
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (cluster.isWorker) {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`I am worker #<span class="hljs-subst">${cluster.worker.id}</span>`</span>);
|
||
}</code></pre>
|
||
<h2><code>cluster.workers</code><span><a class="mark" href="#cluster_cluster_workers" id="cluster_cluster_workers">#</a></span></h2>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.7.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a></li>
|
||
</ul>
|
||
<p>A hash that stores the active worker objects, keyed by <code>id</code> field. Makes it
|
||
easy to loop through all the workers. It is only available in the master
|
||
process.</p>
|
||
<p>A worker is removed from <code>cluster.workers</code> after the worker has disconnected
|
||
<em>and</em> exited. The order between these two events cannot be determined in
|
||
advance. However, it is guaranteed that the removal from the <code>cluster.workers</code>
|
||
list happens before last <code>'disconnect'</code> or <code>'exit'</code> event is emitted.</p>
|
||
<pre><code class="language-js"><span class="hljs-comment">// Go through all workers</span>
|
||
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">eachWorker</span>(<span class="hljs-params">callback</span>) </span>{
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> id <span class="hljs-keyword">in</span> cluster.workers) {
|
||
callback(cluster.workers[id]);
|
||
}
|
||
}
|
||
eachWorker(<span class="hljs-function">(<span class="hljs-params">worker</span>) =></span> {
|
||
worker.send(<span class="hljs-string">'big announcement to all workers'</span>);
|
||
});</code></pre>
|
||
<p>Using the worker's unique id is the easiest way to locate the worker.</p>
|
||
<pre><code class="language-js">socket.on(<span class="hljs-string">'data'</span>, <span class="hljs-function">(<span class="hljs-params">id</span>) =></span> {
|
||
<span class="hljs-keyword">const</span> worker = cluster.workers[id];
|
||
});</code></pre>
|
||
<!-- API END -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</body>
|
||
</html>
|