我使用NodeJS和PhantomJS。我的目标是创建具有节点集群的4x节点实例,每个实例具有2个幻像子节点。我的代码看起来像这样:
cluster.js:
var numCPUs = 4;
if (cluster.isMaster) {
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
cluster.fork();
});
} else {
require("./app");
}
App.js看起来像这样:
var instances = [];
var phantom = require('phantom');
function InstanceManager(instCount) {
for (var i = 0; i < instCount; i++) {
phantom.create(function(phantomInstance) {
instances.push({
cycle: 0,
locked: false,
instance: phantomInstance
});
});
}
}
InstanceManager(2);
setInterval(function() {
var i = 0;
console.log('--' + instances.length);
}, 5000);
因此,在节点控制台中运行cluster.js
之后,每5秒应该是:
--2
--2
--2
--2
但是看起来像这样:
--0
--0
--0
--8
为什么幻影实例没有附加到合适的工作人员身上?
答案 0 :(得分:3)
问题似乎在于幻像模块,与群集无法正常工作。如果你用一种测试双重替换它,比如
var phantom = {
create: function (callback) {
setImmediate(callback);
}
};
你得到了预期的全2输出。为了继续我的调查,我修改了node_modules/phantom/phantom.js
以获得问题发生的最小设置。就是这样:
var http = require('http'), shoe = require('shoe'), spawn = require('win-spawn');
exports.create = function(cb) {
var httpServer, sock;
httpServer = http.createServer();
httpServer.listen(0);
httpServer.on('listening', function() {
var listeningPort = httpServer.address().port;
spawn('phantomjs', [].concat([__dirname + '/shim.js', listeningPort]));
});
sock = shoe(cb);
return sock.install(httpServer, '/dnode');
};
这里发生的是启动侦听服务器,然后启动一个phantomjs进程,该进程通过WebSocket连接到侦听服务器,并写入它,然后调用回调cb()
。您可以通过查看shim.js
并尝试一下来了解这一理解。
那么问题是什么!?好吧,如果您console.log()
listeningPort
,您会看到您获得相同的端口8次。因此,每次调用phantom.create()
时,您都会重复使用相同的侦听服务器,因此只在一个进程中调用回调。
这似乎是您尝试在端口0上侦听时使用的Node版本的一种特殊行为。这也可以解释为什么在使用其他版本的Node时,问题并未发生(根据评论 以上)。这是我的gist,它隔离了这种反直觉的行为。
解决方案是在调用phantom.create()
时指定端口,并使用8个不同的端口,例如phantom.create(fn, { port: YOUR_PORT })
中的app.js
。