Node.JS:处理服务器每分钟最大请求的最佳方法

时间:2017-08-06 20:25:30

标签: javascript node.js api request limit

我很抱歉,如果这个问题已经得到解答,我希望我没有违反任何SO规则,如果是这样,事先我道歉...... 我想知道处理请求限制器的最佳方法是什么?我在网上看过一堆限流器和速率限制器,但我不确定它是如何适用于我的情况。

我正在做一堆基于Array的[OUTGOING] request-promises,在服务器上我每分钟只能发出90个请求。我的请求 - 承诺由此命令生成:return Promise.all(array.map(request))

我想这样处理它:

var i = 0;

return rp({
        url: uri,
        json: true,
      }).then((data) => {
        if (i <=90) {
          i ++;
          return data;
        } else {
          return i;
        }
      });

但是我不确定它是否是一种真正有效的方法来处理它,我不知道如何处理时间关系......:S

先谢谢你的帮助,对不起,我还是个初学者......

3 个答案:

答案 0 :(得分:2)

您可以使用setInterval。查看文档here

var requestCount = 0;

setInterval(function(){
    // Every 60 seconds, reset the count
    requestCount = 0;
}, 60000);

// There needs to be an additional check before calling rp,
// that checks for requestCount > 90, and returns before starting the request.

rp({
    url: uri,
    json: true,
})
.then((data) => {
    requestCount++;
    return data;
});

答案 1 :(得分:1)

可能每分钟只做90次请求。您可以使用函数伪随机承诺:

function multiRequest(urls, maxPerMinute){
 return new Promise(function(cb){
   var result = [];
   //iterate recursively
   (function next(i){
     //if finished resolve promise
     if(i>=urls.length) return cb(result);
      //get all requests
      var requests = Promise.all(urls.slice(i,i+maxPerMinute).map(request));

      //if the requests are done, add them to result
      requests.then(data=>result.push(...data));        

      //if the requests + one minute done, conginue with next
      Promise.all([
        requests,
        new Promise(res=>setTimeout(res,1000*60))    
      ] ).then(_=>next(i+maxPerMinute))
 })(0);
 });
}

像这样使用:

 multiRequests(["google.com","stackoverflow.com"],90)
  .then(([google,so])=>...);

答案 2 :(得分:1)

如果请求是从不同的代码部分启动的,那么实现某事就像服务器队列一样等待请求,直到允许这样做为止。通用处理程序:

var fromUrl = new Map();

function Server(url, maxPerMinute){
 if(fromUrl.has(url)) return fromUrl.get(url);
 fromUrl.set(url,this);

  this.tld = url;
  this.maxPerMinute = maxPerMinute;
  this.queue = [];
  this.running = false;

}


  Server.prototype ={
   run(d){
    if(this.running && !d) return;
    var curr = this.queue.shift();
    if(!curr){
      this.running = false;
      return;
    }
   var [url,resolve] = curr;
   Promise.all([
     request(this.tld + url),
     new Promise(res => setTimeout(res, 1000*60/this.maxPerMinute)
    ]).then(([res]) => {
       resolve(res);
       this.run(true);
    });
  },
  request(url){
   return new Promise(res => {
      this.queue.push([url,res]);
      this.run();
    });
  }
};

module.exports = Server;

可以这样:

 var google = new require("server")("http://google.com");

google.maxPerMinute = 90;

google.request("/api/v3/hidden/service").then(res => ...);