我正在尝试实现一个使用cluster. 问题是整个父作用域与预期的集群代码一起分叉。我在用 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');
////////////////////////////////////////////////////////
Run Code Online (Sandbox Code Playgroud)
所以我会冒险回答。仔细查看节点文档,有一个cluster.setupMaster可以覆盖默认值。a 上的默认值cluster.fork()是执行当前脚本,带有“工作文件的文件路径。(默认值=process.argv[1])”
https://nodejs.org/docs/latest/api/cluster.html#cluster_cluster_settings
因此,如果另一个模块使用 cluster.fork() 调用导入脚本,它仍将使用 process.argv[1] 的路径,这可能不是您期望的路径,并且会产生意想不到的后果。
所以我们不应该像官方文档建议的那样在同一个文件中初始化集群 master 和 worker。将 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');
////////////////////////////////////////////////////////
Run Code Online (Sandbox Code Playgroud)
你应该只看到 'hello' 一次而不是 1 * Number of CPUs
| 归档时间: |
|
| 查看次数: |
2605 次 |
| 最近记录: |