对第 3 方 API 的请求进行速率限制

Posted

技术标签:

【中文标题】对第 3 方 API 的请求进行速率限制【英文标题】:Rate limiting requests to a 3rd-party API 【发布时间】:2016-07-20 12:52:49 【问题描述】:

我的代码:

const limit = require('simple-rate-limiter')
const request = limit(require('request').defaults(
    gzip: true
)).to(15).per(10 * 1000) // 15 requests per 10 seconds

request(API_ENDPOINT, callback) // call API thousands of times

库:simple-rate-limiter 和著名的 request 库。


我需要调用第 3 方 API 数千次,每 10 秒只允许 15 个请求。上面的代码没有正确限制我的请求,所以服务器发送了一个429 Too Many Requests HTTP 状态代码。

我可以一次发送 15 个请求,但程序必须等待 10 秒才能发送更多请求,否则它会再次收到 429 响应。

我认为这是因为与服务器的连接需要数百毫秒到几秒 (300ms-2s)。所以我的请求时间和服务器收到请求的时间是不一样的。

来自服务器的响应包含 Date 标头。可以以某种方式正确限制请求吗?有没有一个图书馆可以让这变得容易?即使在实施正确的速率限制之后,如果您收到 429 响应,是否也有一种简单的方法可以重试?

【问题讨论】:

您想欺骗 API 并调用端点超出其限制?我没听错吗? 不,我要按限制调用。如果我不这样做,我会收到一个我不想收到的429 HTTP 响应。 【参考方案1】:

好的,所以方法是检查从开始到结束通话的时间。我假设每 667 毫秒调用一次 API 是安全的。

var startTime,
    endTime;

function timeDiff() 
    return (endTime.getTime() - startTime.getTime());

function startRequest() 
    startTime = new Date();
    request(API_ENDPOINT, requestCallback)

function requestCallback(data) 
   //do what you please with data
   endTime = new Date();  
   var diff = timeDiff(); 
   if(diff < 667) 
        //To early to start API, need to wait.
        setTimeout(startRequest, 667 - diff);
    else 
        //It is fine to start request now.
        setTimeout(startRequest);
   


startRequest();

此代码将在调用完成后立即继续调用 API,除非它的完成速度快于 667 毫秒。

【讨论】:

以上是关于对第 3 方 API 的请求进行速率限制的主要内容,如果未能解决你的问题,请参考以下文章

Azure API 响应中缺少速率限制标头

aiohttp:限制并行请求的速率

为 APIM 下的所有 API 实例创建请求速率限制

Instagram 速率限制

如何限制/速率限制请求以防止 Axios 出现 429 错误

instagram api 速率限制说明