node.js 集群模块如何允许多个子进程监听同一个端口?

Rya*_*ggs 6 port fork node.js node-cluster

使用 Node.JS 和cluster模块。

我试图了解多个分叉子进程如何在同一个端口上侦听。

例如,使用cluster模块我们可以这样做:

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}`);
    });

}
Run Code Online (Sandbox Code Playgroud)

此代码派生多个进程,所有进程都调用listen同一个端口。我不清楚所有进程如何绑定同一个端口并且仍然能够确定哪个进程获取端口流量。这实际上是一种错觉,而是主进程实际上是唯一一个绑定端口并将请求随机传递给分叉子进程的进程?(如果是这种情况,是不是对性能有影响?)

感谢您帮助我了解所有子进程如何同时侦听同一端口。

请注意,此示例在 Windows 机器上运行,但如果我理解正确,它与 Windows 和 Linux 兼容。

zer*_*298 3

来自文档集群:它是如何工作的

集群模块支持两种分配传入连接的方法。

第一种(也是除 Windows 之外的所有平台上的默认方法)是循环方法,其中主进程侦听端口,接受新连接并以循环方式将它们分发给工作进程,其中一些构建- 聪明地避免工作进程过载。

第二种方法是主进程创建监听套接字并将其发送给感兴趣的工作进程。然后工作人员直接接受传入连接。

“顶层”进程是绑定端口的进程。IPC通道自动分配给子进程。“工作人员可以共享 TCP 连接”。

另一个重要部分是exclusive的属性server.listen()

如果exclusivefalse(默认),则集群工作人员将使用相同的底层句柄,从而允许共享连接处理职责。当exclusive为 时true,句柄不被共享,并且尝试端口共享会导致错误。下面显示了侦听独占端口的示例。

因此,如果您告诉它们,您可以让它们全部尝试(并失败)绑定到同一端口exclusive,但默认情况下(这就是您的示例中的情况),它们共享句柄,从而允许分发连接。

  • 我仍在试图弄清楚集群工作人员如何共享相同的句柄。我知道他们这样做,我只是不知道它在代码中的位置。OP问题中所示的集群初始化代码仅显示工作人员调用“.listen()”,这与主监听和分发相反。这是怎么回事? (2认同)
  • @RyanGriggs - 大规模执行此操作的硬件辅助方法是使用专门的负载均衡器或代理(例如 nginx)在一组侦听服务器之间分发请求。这样,您不仅可以在同一服务器上的不同进程之间进行负载平衡,还可以在不同服务器之间进行负载平衡。因此,规模是有层次的。单个服务器上的集群是单个 Node.js 进程的下一层扩展。当然,通过涉及更多硬件,甚至最终涉及边缘服务器和多个数据中心,还可以达到更高的层次。 (2认同)