尝试在节点群集后面扩展时,phantomjs-node崩溃 [英] phantomjs-node crashes when attempting to scale behind node-cluster
问题描述
相关的GitHub问题: https://github.com/sgentle/phantomjs-node/Issues/280
Associated GitHub issue: https://github.com/sgentle/phantomjs-node/issues/280
我有一个简单的应用程序,可以执行以下操作:
I have a simple app that does the following:
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
端点,并且一切都会按预期进行.
As long as I run this in WebStorm, it runs just fine and I can hit the /foo
endpoint w/ as many concurrent requests as I want and everything works as expected.
但是,只要我尝试将其扩展到带pm2 start -i 0 phantomapp.js
的PM2之后,只要我没有对它提出太多请求,一切就都可以正常工作.第二个我打开两个浏览器窗口,然后在两个窗口中都单击刷新",在pm2 logs
中得到以下内容.此时,由PM2管理的所有8个进程都消失了"!我究竟做错了什么?? :
But as soon as I try to scale it behind PM2 w/ pm2 start -i 0 phantomapp.js
, everything still works fine as long as I don't throw too many requests at it. The second I open up two browser windows and hit refresh in both, I get the following in pm2 logs
. At which point, ALL 8 processes managed by PM2 just "disappear"! What am I doing wrong?? :
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
您可以使用节点本地群集重现相同的问题:
You can reproduce the same issue using node-native cluster:
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个以上请求时,会在控制台中产生以下错误:
Which produces the following error in the console when attempting to handle > 1 request concurrently:
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)
推荐答案
我尝试了此要点,我就能创建幻像浏览器并获得响应.
I tried with this gist and I'm able to create the phantom browser and to get a response.
- 如果我在
localhost:3000/foo
上运行两个选项卡,则仅当第一个选项卡结束时才会生成第二个选项卡. - 如果我在浏览器中运行多个并发请求 (chrome),我也会收到错误消息.
- 如果我尝试运行的请求(来自bash的请求)多于崩溃的集群数量.
- If I run two tabs on
localhost:3000/foo
, the second will be spawned only when the first has ended. - If I run more than two concurrent requests in my browser (chrome), I get the error too.
- If I try to run more requests (from a bash) than the number of clusters it crashes.
如果我从bash脚本运行请求(小于或等于集群数),则根本不会崩溃.
If I run requests (less than or equal to the number of cluster) from a bash script it doesn't crash at all.
另外,我注意到,使用bash脚本可以同时运行所有内容:
Also, I'm noticing that with the bash script I'm running everything in concurrence:
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);
这意味着该工人不再处于循环中.
Meaning that the worker is not in the round robin anymore.
我不认为这与PM2有关,但存在错误. PM2不应崩溃.我建议您通过引用此stackoverflow来报告问题.如果是节点错误,则不确定是否可以修复.
I don't think that this is direclty related to PM2 but there is a bug. PM2 should not crash. I suggest your report an issue by quoting this stackoverflow. Not sure that it can be fixed if it's a node bug though.
目前暂时无法解决此问题,但您可以查看 nodejs问题.我读过iojs解决了这个问题,也许您可以尝试一下;).
Sadly there are no fix for this at the moment but you can take a look at a nodejs issue. I've read that iojs fixed this, maybe you can give it a try ;).
另一个相关的stackoverflow: NodeJS群集意外的assert.AssertionError .
Another related stackoverflow: NodeJS Cluster unexpected assert.AssertionError.
这篇关于尝试在节点群集后面扩展时,phantomjs-node崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!