【问题标题】:Node cluster not spawning phantom instances in the proper worker节点集群没有在适当的工作人员中产生幻影实例
【发布时间】:2014-11-06 02:55:46
【问题描述】:

我将 NodeJS 与 PhantomJS 一起使用。我的目标是使用节点集群创建 4 个节点实例,每个实例都有 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

为什么幻影实例没有附加到正确的工作人员?

【问题讨论】:

  • 当您将setInterval 超时增加到 10000 或 15000 时会发生什么? 2个实例的启动可能太慢了5秒甚至10秒。
  • 还是一样的结果:(
  • 我正在运行节点 0.10.26,它可以工作
  • @Deepsy 有趣的问题!!!我今天完成了我的答案,它在下面。我不得不省略细节,但我希望它足够清楚。

标签: node.js phantomjs cluster-computing child-process node-cluster


【解决方案1】:

问题似乎出在幻像模块上,无法在集群中正常工作。如果您将其替换为某种测试替身,例如

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() 时,您都会以某种方式重用相同的侦听服务器,因此您的回调仅在一个进程中被调用。

这似乎是您正在使用的 Node 版本在尝试侦听端口 0 时的一种特殊行为。这也可以解释为什么使用另一个版本的 Node,问题没有发生(根据评论 更多)。这是我的gist,它隔离了这种违反直觉的行为。

解决方法是在调用phantom.create()时指定一个端口,并在你的app.js中使用8个不同的端口,例如phantom.create(fn, { port: YOUR_PORT })

【讨论】:

  • 太棒了!你是真正的 MVP!
猜你喜欢
  • 1970-01-01
  • 2013-04-24
  • 2016-01-15
  • 1970-01-01
  • 2015-04-28
  • 1970-01-01
  • 2017-01-29
  • 2016-07-08
  • 2021-09-11
相关资源
最近更新 更多