node.js - Node.js 集群 - 为什么脚本在没有明显原因的情况下多次运行?
问题描述
所以我把下面的代码写到了一个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;博士; 我想出的真正答案是“魔法”的发生,因为 cluster.fork() 在效果中说:创建一个新环境(V8)来执行由 process.argv[1] 定义的“一些 javascript 模块”;这恰好是 MyScript.js 的完整路径;
解决方案
将集群视为分叉进程,当您进行for
迭代时,您将创建多个fork
将运行相同脚本的子进程(部分),但是当他们检查if
语句时,他们将执行else
部分,因为集群的主进程(即只有一个)是创建现在正在检查if
.
运行的进程数与您计算机上的 CPU 数相同,因此,例如,如果您的 CPU 有 8 个内核,则您希望有 8 个工作线程在运行。
所以基本上,你希望只运行一次以下
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 不同)是,当它执行 a 时,fork
它会创建 V8 引擎的新实例,并且每次创建新进程时都会使代码完全执行。函数名称fork
具有误导性,因为它不会复制您的进程并从您所在的位置开始运行,而是生成一个新进程,从而使该进程再次运行整个脚本。
推荐阅读
- r - 自动识别变量之前在 R 的回归中已被分解
- c# - 控制器中的 Asp.Net Core 单元测试删除方法
- wordpress - htaccess | 阿帕奇 | 最佳实践 | WordPress 插件 | 允许覆盖
- python - 如果为 key 关键字参数提供 map 和 lambda 组合,Python sorted() 将引发错误
- php - 使用 Json 进行 MySql 查询
- shell - 如何将远程机器上 jenkins 中的 SSH 中的变量导出到本地机器上的 shell?
- bixby - Bixby NL 使用整数数据类型
- lisp - 如何在 Lisp 中生成一系列 Pell 数字而不是特定数字
- mysql - MYSQL 选择 3 个随机记录,其中至少一个记录字段具有一定的值
- python - 保存的 csv 的 pd.to_csv 日期格式不同