2015-05-28 3 views
2

Associated GitHub вопроса: https://github.com/sgentle/phantomjs-node/issues/280phantomjs-узел происходит сбой при попытке масштабирования за узел кластера

У меня есть простое приложение, которое выполняет следующее:

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 с количеством одновременных запросов, как я хочу, и все работает так, как ожидалось.

Но как только я пытаюсь масштабировать его позади PM2 w/pm2 start -i 0 phantomapp.js, все по-прежнему работает нормально, пока я не бросаю слишком много запросов. Во-вторых, я открываю два окна браузера и нажимаю обновление в обоих, я получаю следующее в pm2 logs. В этот момент все 8 процессов, управляемых PM2, просто «исчезают»! Что я делаю не так?? :

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 [email protected] -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) 

ответ

0

Я пробовал с this gist, и я могу создать фантомный браузер и получить ответ.

  • Если я запустил две вкладки на localhost:3000/foo, второй будет порожден только тогда, когда первый закончен.
  • Если я запускаю более двух одновременных запросов в моем браузере (хром), я также получаю ошибку.
    • Если я попытаюсь запустить больше запросов (от bash), чем число кластеров, он сработает.
  • Если я запускаю запросы (меньше или равные числу кластеров) из сценария bash, он вообще не падает.

    Кроме того, я заметил, что со сценарием Баша я бегом все в согласии:

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

Ошибка вы видите приходит от this assertion:

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

Это означает, что рабочий больше не находится в круговой игре.

Я не думаю, что это связано с PM2, но есть ошибка. PM2 не должен падать. Я предлагаю ваш report an issue, указав этот stackoverflow. Не уверен, что он может быть исправлен, если это ошибка узла.

К сожалению, на данный момент никаких исправлений для этого нет, но вы можете взглянуть на nodejs issue. Я читал, что iojs исправил это, возможно, вы можете попробовать попробовать;).

Другой связанный переток: NodeJS Cluster unexpected assert.AssertionError.

+1

Да ..Я не думаю, что это проблема PM2. Я обновил вопрос с более простым примером, который напрямую обрабатывает вилки кластера, и туда же возникает одна и та же ошибка. «Это означает, что рабочий больше не в круговой робин». Поскольку это утверждение находится в '' 'RoundRobinHandle.add'', не означает ли это обратное? Что рабочий, которого он пытается добавить, уже находится в rr? Я на 100% уверен, что это связано с тем, как phantomjs-node использует дочерний_узел узла для связи с процессами w/phantomjs. Я обновлю ответ с проблемой github, которую я создал для phantomjs-node – RavenHursT

+0

Мне кажется, что это не ошибка phatomjs, а проблема nodejs, см. Мои последние 2 ссылки. Можете ли вы попробовать с iojs? – soyuka

+0

Столбец ошибок в проблеме nodejs, на которую вы ссылаетесь, указывает на '' 'SharedHandle.add''', а не' '' RoundRobinHandle.add''', не уверен, что оба случая одинаковы? – RavenHursT

Смежные вопросы