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

3

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

代码运行良好,但我不理解:

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

我原以为会出现以下信息:

Error: listen EADDRINUSE: address already in use :::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");
  });
2个回答

12
我之前也曾想过这个问题并进行了调查。
子进程并不监听同一个端口。主进程接收到的套接字连接会被委派给子进程。
实际上,情况有些欺骗性,因为你确实可以在每个子进程中看到server.listen()。但是,在.listen()内部,有一些魔法知道这个进程应该是一个集群进程,因此它们不是以传统意义上的侦听方式(这确实会导致你提到的错误)来侦听,而是在等待来自其父进程的委派套接字。
如果我设计这个功能,我可能不会将其隐藏在.listen()中,从而引起混淆。我会提供另一种方法在这种情况下使用,以实现这种特殊行为。
如果您想了解更多信息,请参考以下资源: server.listen()源代码,在某些情况下它会调用listenInCluster()
Net文档中,关于server.listen()有特殊处理的参考。 listenInCluster()源代码就是在这里执行的。
  // Get the master's server handle, and listen on it
  cluster._getServer(server, serverQuery, listenOnMasterHandle);

原始设计中聚类似乎是一个重要的特性,但实际使用时并没有像最初预期的那样多。当然这只是我的猜测... - Mike M
@MikeM - 在Node.js拥有WorkerThreads之前,需要使用集群或在子进程中运行专门的代码才能运行CPU密集型代码并且不干扰主线程中的提示事件循环处理。当然,某种形式的集群是将服务器扩展到一个进程无法处理的经典因素。但是,我认为你是正确的,许多应用程序不需要使用它。 - jfriend00

0

子进程共享父进程的文件描述符,因此它们最终会监听同一端口。这个答案可能可以消除疑惑。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接