Node.js 集群 - 为什么脚本 运行 多次无明显原因?

Node.js Clusters - why is the script running multiple times with no obvious reason?

所以我将下面的代码写入了一个 MyScript.js 文件; (直接取自 https://nodejs.org/api/cluster.html 的 node.js 文档)

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

console.log("I'm at the top"); //PAY ATTENTION TO THIS LINE

if (cluster.isMaster) {
  console.log(`Master ${process.pid} is running`);

  // Fork workers.
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} died`);
  });
} else {
  // Workers can share any TCP connection
  // In this case it is an HTTP server
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('hello world\n');
  }).listen(8000);

  console.log(`Worker ${process.pid} started`);
}

当我运行它与

>node MyScript.js

,它在命令提示符中输出以下内容:

I'm at the top...
Master 24632 is running
I'm at the top...
Worker 25536 started
I'm at the top...
Worker 17524 started
I'm at the top...
Worker 19020 started
I'm at the top...
Worker 11352 started

如何运行 IF 部分和 ELSE 部分?导致 MyScript.js 多次变为 运行 的魔法在哪里?!

更新:tl;dr; 从那以后我得出的真正答案是“神奇”的发生,因为 cluster.fork() in effects 表示:创建一个新环境 (V8) 来执行 process.argv[1] 定义的“一些 javascript 模块”;这恰好是 MyScript.js;

的完整路径

将集群视为分叉进程,当您执行 for 迭代时,您正在创建多个子进程(fork 部分),它们将 运行 相同的脚本但是当他们检查 if 语句时,他们将执行 else 部分,因为集群的主机(只有一个)是创建现在正在检查 if 的进程的主机.

运行 的进程数与您计算机上的 CPU 的进程数相同,例如,如果您的 CPU 有 8 个核心,你会期望有 8 个工人 运行ning.

所以基本上,您希望 运行 只有一次以下

console.log(`Master ${process.pid} is running`);

// Fork workers.
for (let i = 0; i < numCPUs; i++) {
  cluster.fork();
}

cluster.on('exit', (worker, code, signal) => {
  console.log(`worker ${worker.process.pid} died`);
});

但是是下面的数倍(因为你是这样配置的,所以你电脑里的 CPU 数量是一样多)

// Workers can share any TCP connection
// In this case it is an HTTP server
http.createServer((req, res) => {
  res.writeHead(200);
  res.end('hello world\n');
}).listen(8000);

console.log(`Worker ${process.pid} started`);

然后,当子进程(不是主进程)完成时,您将看到以下内容 console.log

console.log(`worker ${worker.process.pid} died`);

编辑:

那么为什么 运行 console.log("I'm at the top"); 多次呢? Node 所做的(与 C 不同)是当它执行 fork 时,它会创建一个新的 V8 引擎实例,这会使代码在您每次创建新进程时完全执行。 函数名称 fork 具有误导性,因为它不会复制您的进程并从您所在的位置开始 运行ning,而是生成一个新进程,使进程成为 运行 整个剧本。