- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试实现一个使用 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/
我是一名优秀的程序员,十分优秀!