ZombieJS:从for循环中反复调用时间歇性地崩溃

时间:2016-02-22 20:29:08

标签: javascript node.js heroku assert zombie.js

我在Heroku上有一个ZombieJS节点服务器从互联网上删除数据。从客户端的for循环调用服务器代码。循环的每次迭代都会产生一个服务器调用,这使得Zombie刮擦。有时,服务器会因以下错误而崩溃。它只发生在for循环的多次迭代时。

如何使代码足够健壮以处理多个同时进行的客户端调用,每个调用都有一个for循环。

代码:

var express = require('express');
var app = express();
var Browser = require('zombie');    // tried changing var to const; no difference
var assert = require('assert');

app.set('port', (process.env.PORT || 5000));

var printMessage = function() { console.log("Node app running on " + app.get('port')); };

var getAbc = function(response, input)
{
    var browser = new Browser(); 
    browser.userAgent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0'; 
    browser.runScripts = true;
    var url = "http://www.google.com/ncr"; 

    browser.visit(url, function() {
        browser.fill('q', input).pressButton('Google Search', function(){
            // parsing number of results from browser object

            response.writeHead(200, {'Content-Type': 'text/plain'});
            response.end(numberOfSearchResults); 
        });
    });
}

var handleXyz = function(request, response)
{
    getAbc(response, request.query.input); 
}

app.listen(app.get('port'), printMessage); 
app.post('/xyz', handleXyz); 

错误:

 assert.js:86
   throw new assert.AssertionError({
              ^
 No open window with an HTML document
     at Browser.field (/app/node_modules/zombie/lib/index.js:811:7)
     at Browser.fill (/app/node_modules/zombie/lib/index.js:903:24)
     at /app/cfv1.js:42:11
     at done (/app/node_modules/zombie/lib/eventloop.js:589:9)
     at timeout (/app/node_modules/zombie/lib/eventloop.js:594:33)
     at Timer.listOnTimeout (timers.js:119:15)

我有一个使用HorsemanJS / PhantomJS的类似项目,它以类似的方式失败了(我也坚持了!):NodeJS server can't handle multiple users

2 个答案:

答案 0 :(得分:1)

一般来说,我认为您应该小心,或者只是避免向远程服务器生成大量未经请求的请求。许多网站会限制您和/或开始拒绝连接。话虽如此,我相信在这种特殊情况下我找到了问题的根源。

我测试了代码段,对于这种特殊情况,如果您发出太多请求,Google会重置连接。重置连接后,其中一个变量最终会失败。

重置连接时出现的错误:

  zombie TypeError: read ECONNRESET
    at zombie/lib/pipeline.js:89:15
    at tryCatcher (zombie/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (zombie/node_modules/bluebird/js/release/promise.js:497:31)
    at Promise._settlePromise (zombie/node_modules/bluebird/js/release/promise.js:555:18)
    at Promise._settlePromise0 (zombie/node_modules/bluebird/js/release/promise.js:600:10)
    at Promise._settlePromises (zombie/node_modules/bluebird/js/release/promise.js:679:18)
    at Async._drainQueue (zombie/node_modules/bluebird/js/release/async.js:125:16)
    at Async._drainQueues (zombie/node_modules/bluebird/js/release/async.js:135:10)
    at Immediate.Async.drainQueues [as _onImmediate] (zombie/node_modules/bluebird/js/release/async.js:16:14)
    at processImmediate [as _immediateCallback] (timers.js:383:17)

我将原始错误进一步降低,但问题的根源实际上是因为上述原因。当发生上述情况时,它会导致document.documentElement为false-y值,并随后导致字段函数中zombie / lib / index.js中的此断言失败:

assert(this.document && this.document.documentElement, 'No open window with an HTML document');

我认为最简单的解决方案是在客户端处理错误并尝试优雅地恢复。

答案 1 :(得分:0)

我看到你正在为每个调用创建一个Browser对象的新实例。我的猜测是以前的#34;浏览器"当下一个呼叫试图打开另一个呼叫时,垃圾收集器仍处于关闭状态,或者尚未处理。尝试将浏览器的实例化移动到getAbc()

之外