【问题标题】:Node.js API Request limit with request-promise带有 request-promise 的 Node.js API 请求限制
【发布时间】:2016-10-29 03:57:16
【问题描述】:

我正在尝试从我的 node.js 应用程序中访问 REST API 端点,如下所示:

var people = [];
for(var i=0; i<n; i++) {
    //create person
    people.push(person);
}
return Promise.all(people.map(create3APIRequestPromises));

其中 create3APIRequestPromises 大致如下:

// APIRequestPromise = require('request-promise')(options);
return Promise.all([APIRequestPromise1, APIRequestPromise2, APIRequestPromise3]);

代码对于少数人都可以正常工作,但是如果我增加太多,它就会开始失败。我相信这个失败是由提供 REST API 的服务限制我的使用引起的。所以,我的问题是限制我发送的请求数量的最佳方法是每秒 10 个。

我已经阅读了有关 node-rate-limiter 的信息,但我看不出它如何符合我上面使用 'request-promise' 编写的承诺(也许这个模块不可能,所以也许你可以提出替代方案)。

谢谢。

【问题讨论】:

标签: javascript node.js limit throttling


【解决方案1】:

我认为在您的情况下,最好在发出请求之间使用简单的时间填充。为此,您应该将请求分成系列并延迟每个组。我意识到example。用法是:

// Create timepad function
let timePad = createTimePad(5, 10e3); // 5 requests each 10 seconds

// Iterate over people
return Promise.all(
  people.map(
    (human) => timePad().then(() => create3APIRequestPromises(human))
  )
);

时间垫创建功能:

// Create timepad function where timeout is timeout between calls and series is the maximum
// number of calls that will be done simultaneously
function createTimePad(series = 10, timeout = 1000) {
  let seriesCounter = series;
  let delay = timeout;

  return () => {
    return new Promise((resolve) => {
      if (seriesCounter < 1) {
        delay += timeout;
        seriesCounter = series;
      }

      setTimeout(resolve, delay);

      seriesCounter -= 1;
    });
  };
}

这非常简单,可以根据您的意愿将请求分成大小可变的组。

【讨论】:

    【解决方案2】:

    嗯,这确实是一个好问题。我有同样的问题,意识到还没有人解决它,并开始实现quota。它已经涵盖了您的用例。

    像这样创建你的经理:

    var quota = require('quota');
    
    var manager = new quota.Manager({
        backoff: 'timeout'
    });
    
    // 10 new requests per second
    manager.addRule({
        name: 'main',
        limit: 10,
        window: 1000,
        throttling: 'window-sliding',
        queueing: 'fifo',
        resource: 'requests'
    });
    
    var quotaServer = new quota.Server();
    quotaServer.addManager('custom', manager);
    
    var quotaClient = new quota.Client(quotaServer);
    

    然后通过这个包装器调用你的每个请求:

    var request = require('request-promise');
    
    function requestThrottled(options) {
    
        var _grant;
    
        return quotaClient.requestQuota('custom', {}, { requests: 1 }, {
            maxWait: 60000 // Each request will be queued for 60 seconds and discarded if it didn't get a slot to be executed until then
        })
                .then(function (grant) {
    
                    _grant = grant;
    
                    return request(options);
    
                })
                .finally(function () {
    
                    if (_grant) {
                        _grant.dismiss();
                    }
    
                });
    
    }
    

    您可以像以前一样提出您的要求:

    Promise.all([
        requestThrottled(optionsRequest1),
        requestThrottled(optionsRequest2),
        requestThrottled(optionsRequest3)
    ])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-09
      • 2019-12-08
      • 1970-01-01
      • 2020-12-23
      • 2012-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多