并行执行NodeJS请求会导致超时

时间:2016-03-15 01:15:14

标签: node.js asynchronous request timeout

以下是我的代码。我用它的索引初始化每个数组元素。然后我使用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]# 

原因是什么?我怎么能避免呢?

1 个答案:

答案 0 :(得分:0)

超时问题

这里有几个问题。

  1. 您正在设置一个激进的超时,因此请求超时是有意义的。我超时的时间越长,请求超时的时间就越少。当我删除超时时,我在多达10 000个parellel请求上获得了0%的失败率(尽管10000需要花费很长时间才能完成)。
  2. 您的代码不是一个非常好的互联网公民。向网络服务器发出1000个或更多并行请求基本上是一个迷你DDOS攻击。您应该尝试在更长的时间段内传播您的请求,以便为Web服务器提供更稳定,更均匀的工作负载。
  3. 代码清晰度改进

    我的代码中还注意到一些可以改进的东西。

    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

    Date.now

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

    可以替换为

    var timestamp = Date.now()
    

    var timestamp = +Date()
    

    有关详细信息,请参阅Date.now