【问题标题】:Parallel executing NodeJS request causes timeout并行执行 NodeJS 请求导致超时
【发布时间】:2016-06-30 06:52:03
【问题描述】:

下面是我的代码。我用它的索引初始化每个数组元素。然后我使用async.each 遍历数组并调用以检索 url 内容。 请求超时设置为 500 毫秒。

var async = require('async');
var request = require('request');
var logger = require('log4js').getLogger();

var url = "http://www.wordpress.com";

var arr=new Array(100);
for ( var i=0; i<arr.length; i++){ arr[i]=i; }
async.each(arr, function(a, cb) {
  var ts1 = (new Date()).getTime();
  request(url, {timeout: 500}, function( err, res, body ) {
    var ts2 = (new Date()).getTime();
    logger.debug(`a=${a}, dt=${ts2-ts1}`);
    if ( err ) {
      logger.debug(`Error: ${err}, dt=${ts2-ts1}`);
      return cb(null);
    }
    else {
      //logger.debug(`OK: ${a}`);
      cb(null);
    }
  });
},
function( err, result) {
});

当数组大小为 100 时,我得到 12 个超时错误:

[root@njs testreq]# node main.js | grep ETIME | wc -l
12
[root@njs testreq]# 

当数组大小为 1000 时,我得到 1000 个超时错误:

[root@njs testreq]# node main.js | grep ETIME | wc -l
1000
[root@njs testreq]# 

原因是什么?我怎样才能避免它?

【问题讨论】:

    标签: node.js asynchronous request timeout


    【解决方案1】:

    超时问题

    这里有几个问题。

    1. 您正在设置主动超时,因此请求超时是有意义的。我超时的时间越长,超时的请求就越少。当我取消超时后,我在多达 10000 个并行请求上的失败率为 0%(尽管 10000 个需要很长时间才能完成)。
    2. 您的代码不是一个很好的互联网公民。向网络服务器发出 1000 个或更多并行请求基本上是一种小型 DDOS 攻击。您应该尝试将您的请求分散在更长的时间段内,以便为网络服务器提供更稳定、更均匀的工作量。

    代码清晰度改进

    我注意到您的代码中还有一些可以改进的地方。

    Array.from

    如果你想创建一个包含 100 个元素的数组,你不必这样做

    var arr = new Array(100)
    for (var i = 0; i < arr.length; i < 0) { arr[i] = i }
    

    您可以将其替换为

    var arr = Array.from({length: 100}, (v, k) => k)
    

    更多信息请见Array.from

    现在日期

    var timestamp = (new Date()).getTime()
    

    可以替换为

    var timestamp = Date.now()
    

    var timestamp = +Date()
    

    更多信息请见Date.now

    【讨论】:

    • 1.没有超时是不可接受的:当数组大小为 1000 2 时,一些请求需要超过 11 秒才能完成。这不是 DDOS,这些是对 RTB 服务器的请求(不是 reali 应用程序中的 wordpress),所以它应该支持我假设的负载。问题是是否有一些我可以调整以避免超时的东西。 3. 感谢 Arry.from() :)
    • 不幸的是,请求将需要尽可能长的时间。您可以等待足够长的时间来获得答案,或者您可以提前挂断。没有办法强制其他站点上的服务器以比它更快的速度处理流量。
    • 我了解我无法让远程服务器在我身边更快地工作。但是我用来连接的服务器是 RTB 广告平台,应该承受这样的负载(例如,请参阅tech.adroll.com 的 RTB 部分)。所以我认为是我做错了什么。
    • 如果你挂断时数据还没有回来,那就是它。他们没有及时回复你。我能说的不多了。您发布的代码看起来很简单,其中隐藏了更多险恶的错误。
    • 嗯,问题出在 NodeJS 设置上,在这里解决了:stackoverflow.com/questions/36018208/…
    猜你喜欢
    • 1970-01-01
    • 2015-09-24
    • 2017-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-29
    • 1970-01-01
    相关资源
    最近更新 更多