gpt4 book ai didi

node.js - 为什么 Node cluster.fork() 在作为模块实现时 fork 父作用域

转载 作者:搜寻专家 更新时间:2023-10-31 23:08:02 24 4
gpt4 key购买 nike

我正在尝试实现一个使用 cluster 的 Node 模块。问题是整个父范围与预期的集群代码一起 fork 。我在为模块编写 Mocha 测试时发现:测试套件将运行多次,而不是一次。

见下文,myModule.js 创建了 N 个 worker,每个 CPU 一个。这些工作人员是 http 服务器,或者可以是其他任何东西。

每次 test.js 运行时,脚本都会运行 N+1 次。在下面的示例中,console.log 在我的四核上运行了 5 次。

有人可以解释这是实现问题还是集群配置问题?有什么方法可以限制 fork() 的范围而不必导入模块(如本解决方案 https://github.com/mochajs/mocha/issues/826 所示)?

/// myModule.js ////////////////////////////////////

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

var startCluster = function(){

if (cluster.isMaster) {
// CREATE A CLUSTER OF FORKED WORKERS, ONE PER CPU
//master does not listen to UDP messages.

for (var i = 0; i < numCPUs; i++) {

var worker = cluster.fork();
}


} else {
// Worker processes have an http server.
http.Server(function (req, res){
res.writeHead(200);
res.end('hello world\n');
}).listen(8000);

}

return
}

module.exports = startCluster;

/////////////////////////////////////////////////

//// test.js ////////////////////////////////////

var startCluster = require('./myModule.js')

startCluster()

console.log('hello');

////////////////////////////////////////////////////////

最佳答案

所以我冒险回答一下。仔细查看 Node 文档,有一个 cluster.setupMaster 可以覆盖默认值。 cluster.fork() 上的默认设置是执行当前脚本,使用“worker 文件的文件路径。(Default=process.argv[1])” https://nodejs.org/docs/latest/api/cluster.html#cluster_cluster_settings

因此,如果另一个模块正在导入带有 cluster.fork() 调用的脚本,它仍将使用 process.argv[1] 的路径,这可能不是您期望的路径,并且会产生意想不到的后果。

所以我们不应该像官方文档建议的那样在同一个文件中初始化集群主 Node 和工作 Node 。谨慎的做法是将 worker 分离到一个新文件中并覆盖默认设置。 (同样为了安全起见,您可以使用 __dirname 添加目录路径)。

cluster.setupMaster({ exec: __dirname + '/worker.js',});

所以这里是更正的实现:

/// myModule.js ////////////////////////////////////

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

var startCluster = function(){
cluster.setupMaster({
exec: __dirname + '/worker.js'
});

if (cluster.isMaster) {
// CREATE A CLUSTER OF FORKED WORKERS, ONE PER CPU
for (var i = 0; i < numCPUs; i++) {
var worker = cluster.fork();
}

}
return
}

module.exports = startCluster;

/////////////////////////////////////////////////

//// worker.js ////////////////////////////////////
var http = require('http');

// All worker processes have an http server.
http.Server(function (req, res){
res.writeHead(200);
res.end('hello world\n');
}).listen(8000);

////////////////////////////////////////////////////////

//// test.js ////////////////////////////////////

var startCluster = require('./myModule.js')

startCluster()

console.log('hello');

////////////////////////////////////////////////////////

你应该只看到一次 'hello' 而不是 1 * CPU 数量

关于node.js - 为什么 Node cluster.fork() 在作为模块实现时 fork 父作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39626750/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com