Ryan Griggs
Ryan Griggs

Reputation: 2758

How does node.js cluster module allow multiple child process to listen on the same port?

Using Node.JS and cluster module.

I am trying to understand how multiple forked child processes can listen on the same port.

For example, using cluster module we can do this:

const port = 443;
...
if (cluster.isMaster) {
    for(let i = 0; i < numCPUs; i++)
    {
        cluster.fork();
    }
...
}
else // Forked child processes:
{
... 
    https.createServer({
        key: fs.readFileSync('server.key'),
        cert: fs.readFileSync('server.cert')
    }, app)
    .listen(port, () => {
        console.log(`HTTPS Listening on port ${port}`);
    });

}

This code forks multiple processes, all of which call listen on the same port. I'm not clear on how all the processes could bind the same port and still be able to determine which process gets the port traffic. Is this actually an illusion, and instead the master process is actually the only one binding the port and passing the requests randomly to the forked children? (If this is the case, isn't there a performance hit?)

Thanks for helping me understand how all the child processes can listen on same port at same time.

NOTE that this example is running on a Windows machine, but if I understand correctly, it is compatible with both Windows and Linux.

Upvotes: 12

Views: 2553

Answers (1)

zero298
zero298

Reputation: 26878

From the docs Cluster: How It Works:

The cluster module supports two methods of distributing incoming connections.

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.

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.

The "top level" process is the one binding the port. The IPC channel automatically distributes to the child processes. "Workers can share the TCP connection".

Another important part is the exclusive property of server.listen().

If exclusive is false (default), then cluster workers will use the same underlying handle, allowing connection handling duties to be shared. When exclusive is true, the handle is not shared, and attempted port sharing results in an error. An example which listens on an exclusive port is shown below.

So you could have them all try (and fail) to bind to the same port if you tell them to be exclusive, but by default (which is what is in your example), they share the handle allowing the connection to get distributed.

Upvotes: 3

Related Questions