尝试缩放节点群集后,phantomjs节点崩溃

相关的GitHub问题: https : //github.com/sgentle/phantomjs-node/issues/280

我有一个简单的应用程序,执行以下操作:

var phantom = require('phantom'), express = require('express'), serve = express(); serve.get('/foo', function (req, res) { try { phantom.create(function (ph) { console.log('Phantom browser created w/ pid: ', ph.process.pid); ph.onError = function (msg, trace) { var msgStack = ['PHANTOM ERROR: ' + msg]; if (trace && trace.length) { msgStack.push('TRACE:'); trace.forEach(function (t) { msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function + ')' : '')); }); } console.log(msgStack.join('\n')); }; ph.createPage(function(page){ page.open('http://www.stackoverflow.com', function(status){ res.json({pageStatus: status}); page.close(); ph.exit(); }); }); }); } catch(e){ console.log(e); throw e; } }); 

只要我在WebStorm中运行它,它运行的很好,我可以按照我的意愿打开/foo端点w /尽可能多的并发请求,一切都按预期工作。

但是一旦我试图在PM2 w / pm2 start -i 0 phantomapp.js后面pm2 start -i 0 phantomapp.js ,只要我不会在它上面pm2 start -i 0 phantomapp.js太多的请求,所有东西都能正常工作。 第二我打开两个浏览器窗口,并在两个刷新,我在pm2 logs 。 在这一点上,PM2pipe理的所有8个进程只是“消失”! 我究竟做错了什么?? :

 PM2: 2015-05-27 18:53:17: [PM2] Error caught by domain: PM2: AssertionError: false == true PM2: at RoundRobinHandle.add (cluster.js:140:3) PM2: at queryServer (cluster.js:480:12) PM2: at Worker.onmessage (cluster.js:438:7) PM2: at ChildProcess.<anonymous> (cluster.js:692:8) PM2: at ChildProcess.emit (events.js:129:20) PM2: at handleMessage (child_process.js:324:10) PM2: at Pipe.channel.onread (child_process.js:352:11) PM2: 2015-05-27 18:53:18: [PM2] Automatic `pm2 update` failed. Killing PM2 daemon and its processes... PM2: 2015-05-27 18:53:18: pm2 has been killed by signal, dumping process list before exit... PM2: 2015-05-27 18:53:18: Stopping app:phantomapp id:0 PM2: assert.js:86 PM2: throw new assert.AssertionError({ PM2: ^ PM2: AssertionError: false == true PM2: at RoundRobinHandle.add (cluster.js:140:3) PM2: at queryServer (cluster.js:480:12) PM2: at Worker.onmessage (cluster.js:438:7) PM2: at ChildProcess.<anonymous> (cluster.js:692:8) PM2: at ChildProcess.emit (events.js:129:20) PM2: at handleMessage (child_process.js:324:10) PM2: at Pipe.channel.onread (child_process.js:352:11) phantomapp-0 (err): Process disconnected from parent ! PM2: [PM2] Spawning PM2 daemon PM2: 2015-05-27 18:53:18: [PM2][WORKER] Started with refreshing interval: 30000 PM2: 2015-05-27 18:53:18: [[[[ PM2/God daemon launched ]]]] PM2: 2015-05-27 18:53:18: BUS system [READY] on port /Users/matthewmarcus/.pm2/pub.sock PM2: 2015-05-27 18:53:18: RPC interface [READY] on port /Users/matthewmarcus/.pm2/rpc.sock PM2: [PM2] PM2 Successfully daemonized PM2: Be sure to have the latest version by doing `npm install pm2@latest -g` before doing this procedure. PM2: [PM2] Stopping PM2... PM2: [PM2][WARN] No process found PM2: [PM2] All processes have been stopped and deleted PM2: 2015-05-27 18:53:18: PM2 is being killed via kill method PM2: 2015-05-27 18:53:18: RPC socket closed PM2: 2015-05-27 18:53:18: PUB socket closed PM2: [PM2] PM2 stopped PM2: 2015-05-27 18:53:19: [PM2][WORKER] Started with refreshing interval: 30000 PM2: 2015-05-27 18:53:19: [[[[ PM2/God daemon launched ]]]] PM2: 2015-05-27 18:53:19: BUS system [READY] on port /Users/matthewmarcus/.pm2/pub.sock PM2: 2015-05-27 18:53:19: RPC interface [READY] on port /Users/matthewmarcus/.pm2/rpc.sock PM2: >>>>>>>>>> PM2 updated PM2: ┌──────────┬────┬──────┬─────┬────────┬─────────┬────────┬────────┬──────────┐ PM2: │ App name │ id │ mode │ pid │ status │ restart │ uptime │ memory │ watching │ PM2: └──────────┴────┴──────┴─────┴────────┴─────────┴────────┴────────┴──────────┘ PM2: Use `pm2 show <id|name>` to get more details about an app 

您可以使用节点本地群集重现相同的问题:

 var cluster = require('cluster'); if(cluster.isMaster){ var cpuCount = require('os').cpus().length; for (var i = 0; i < cpuCount; i++){ cluster.fork(); } cluster.on('exit', function(worker){ console.log('Worker ' + woker.id + ' died. Forking...'); cluster.fork(); }); } else { var phantom = require('phantom'), express = require('express'), serve = express(); serve.get('/foo', function (req, res) { try { phantom.create(function (ph) { console.log('Phantom browser created w/ pid: ', ph.process.pid); ph.onError = function (msg, trace) { var msgStack = ['PHANTOM ERROR: ' + msg]; if (trace && trace.length) { msgStack.push('TRACE:'); trace.forEach(function (t) { msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function + ')' : '')); }); } console.log(msgStack.join('\n')); }; ph.createPage(function(page){ page.open('http://www.stackoverflow.com', function(status){ res.json({pageStatus: status}); page.close(); ph.exit(); }); }); }); } catch(e){ console.log(e); throw e; } }); } 

当试图同时处理> 1请求时,在控制台中会产生以下错误:

 assert.js:86 throw new assert.AssertionError({ ^ AssertionError: false == true at RoundRobinHandle.add (cluster.js:140:3) at queryServer (cluster.js:480:12) at Worker.onmessage (cluster.js:438:7) at ChildProcess.<anonymous> (cluster.js:692:8) at ChildProcess.emit (events.js:129:20) at handleMessage (child_process.js:324:10) at Pipe.channel.onread (child_process.js:352:11) 

我尝试了这个要点 ,我可以创build幻像浏览器并获得响应。

  • 如果我在localhost:3000/foo上运行两个选项卡,第二个选项只有在第一个选项结束时才会生成。
  • 如果我在浏览器 (chrome)中运行两个以上的并发请求,我也会遇到错误。
    • 如果我尝试运行更多的请求(来自bash)而不是崩溃的簇的数量。
  • 如果我从bash脚本运行请求(less于或等于群集的数量),它根本不会崩溃。

    此外,我注意到,与bash脚本我正在运行的一切在并发:

     http GET localhost:3000/foo & http GET localhost:3000/foo & http GET localhost:3000/foo & http GET localhost:3000/foo & 

你看到的错误来自这个断言 :

  assert(worker.id in this.all === false); 

这意味着工人不再在循环中了。

我不认为这是与PM2直接相关,但有一个错误。 PM2不应该崩溃。 我build议你的报告引用这个计算器的问题 。 不知道如果它是一个节点错误,它可以被修复。

可悲的是目前还没有解决这个问题,但你可以看一下nodejs的问题 。 我读过iojs解决这个问题,也许你可以试试看)。

另一个相关的stackoverflow: NodeJS Cluster意外的assert.AssertionError 。