节点集群有多个进程监听同一个端口

Node cluster have multiple processes listen to the same port

我在阅读有关 Node js 中的集群的文章时遇到了一个简单的示例,而主文件创建了四个子进程,每个子进程都监听 8080 端口。

代码运行良好,但我没有得到:

如何让多个子进程监听同一个端口?

我期待收到类似

的消息

错误:侦听 EADDRINUSE:地址已在使用中::8080

const cluster = require("cluster");

if (cluster.isMaster) {
  for (let i = 0; i <= 4; i++) cluster.fork();
} else {
  require("./test.js");
}

test.js

const http1 = require("http");
http1
  .createServer((req, res) => {
    console.log("request1");
    res.write("hello1");
    res.end();
  })
  .listen(8080, () => {
    console.log("begin");
  });

不久前我自己也想知道这个问题并开始挖掘。

child 进程没有监听同一个端口。到主进程的传入套接字连接被委托给 child 个进程。

这里实际发生的是欺骗,因为您肯定会在每个 child 进程中看到 server.listen()。但是,.listen() 内部有一些魔法,它知道这个过程是一个集群过程,所以他们不是在传统意义上实际倾听(这确实会导致你引用的错误),而是在倾听来自他们 parent.

的委托套接字

如果是我设计的,我可能不会将此功能隐藏在 .listen() 中并造成这种混乱。在这种情况下,我会提供一种不同的方法来使用这种特殊行为。

如果您想了解更多信息,这里有一些资源:

Source code for server.listen() 你可以看到它在某些情况下调用 listenInCluster()

Net doc for server.listen()中,提到了聚类时的特殊处理。

listenInCluster() source code 本身在这里执行的行为:

  // Get the master's server handle, and listen on it
  cluster._getServer(server, serverQuery, listenOnMasterHandle);

子进程共享父进程 fd,因此他们最终监听相同的端口。这 answer 可能会消除混淆