ZombieJS:从for循环重复调用时会间歇性地崩溃 [英] ZombieJS: intermittently crashes when called repeatedly from a for loop

查看:230
本文介绍了ZombieJS:从for循环重复调用时会间歇性地崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Heroku上的ZombieJS节点服务器从互联网上删除数据。服务器代码在客户端从循环调用循环。循环的每次迭代都会进行一次服务器调用,这会造成僵尸刮擦。有时候,服务器会在下面的错误中崩溃。它只发生在 for 循环的多次迭代中。

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



代码:

  var express = require('express') ; 
var app = express();
var Browser = require('zombie'); //尝试将var更改为const;没有区别
var assert = require('assert');

app.set('port',(process.env.PORT || 5000));
$ b $ 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;
$ b browser.visit(url,function(){
browser.fill('q',input).pressButton('Google Search',function(){
//解析浏览器对象的结果数

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);

错误:

 < code $ assert.js:86 
throw new assert.AssertionError({
^
在Browser.field上没有打开HTML文档的窗口
(/ app / node_modules /zombie/lib/index.js:811:7)
位于Browser.fill(/app/node_modules/zombie/lib/index.js:903:24)
位于/app/cfv1.js :42:11
完成(/app/node_modules/zombie/lib/eventloop.js:589:9)
超时(/app/node_modules/zombie/lib/eventloop.js:594: 33)
在Timer.listOnTimeout(timers.js:119:15)

我有一个类似的项目,使用HorsemanJS / PhantomJS,它以类似的方式失败(我也坚持这样做): NodeJS服务器无法处理多个用户

解决方案

一般来说,我认为你应该小心或者避免产生大量未经请求的远程请求e服务器。许多网站会阻止你和/或开始拒绝连接。有了这个说法,我相信我在这个特例中找到了问题的根源。



我测试了代码片段,对于这种特殊情况,Google会重置连接if你提出的要求太多了。当连接重置时,其中一个变量最终失败。



重置连接时出现的错误:

  zombie TypeError:在zombie / lib / pipeline.js中读取ECONNRESET 
:89:15 $在tryCatcher中获得
(zombie / node_modules / bluebird / js /release/util.js:16:23)
Promise._settlePromiseFromHandler(zombie / node_modules / bluebird / js / release / promise.js:497:31)
Promise._settlePromise(zombie / node_modules /bluebird/js/release/promise.js:555:18)Promise._settlePromise0(zombie / node_modules / bluebird / js / release / promise.js:600:10)
Promise._settlePromises
(僵尸/ node_modules / bluebird / js / release / promise.js:679:18)
at Async._drainQueue(zombie / node_modules / bluebird / js / release / async.js:125:16)
async._drainQueues(zombie / node_modules / bluebird / js / release / async.js:135:10)
在Immediate.Async.drainQueues [as_onImmediate](zombie / node_modules / bluebird / js / release / asy
at processImmediate [as _immediateCallback](timers.js:383:17)

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

  assert(this.document&&& this.document.documentElement,'没有打开HTML文档的窗口'); 

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

I have a ZombieJS node server on Heroku scrapping data from the internet. The server code is called from a for loop on the client side. Each iteration of the loop makes a server call which makes a Zombie scrape. Sometimes, the server will crash with the error below. It only happens when there is more than one iteration of the for loop.

How can I make the code robust enough to handle multiple simultaneous client calls, each with a for loop.

Code:

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); 

Error:

 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)

I have a similar project using HorsemanJS/PhantomJS which fails in a similar way (I'm stuck on that too!): NodeJS server can't handle multiple users

解决方案

In general, I think you should be careful or just avoid generating a lot of unsolicited requests to remote servers. Many sites will throttle you and/or start rejecting connections. With that said, I believe I found the source of the issue in this particular case.

I tested the code snippet and for this particular case, Google will reset the connection if you make too many requests. When the connection is reset, one of the variables ends up failing an assertion.

The error I get when the connection is reset:

  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)

I get your original error further down, but the source of the problem is actually because of the above. When the above happens, it causes document.documentElement to be a false-y value and subsequently causes this assertion in zombie/lib/index.js in the field function to fail:

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

I think the easiest solution is to handle the error on the client end and try to recover gracefully.

这篇关于ZombieJS:从for循环重复调用时会间歇性地崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆