【问题标题】:Async requests over an API with request rate limiter带有请求速率限制器的 API 上的异步请求
【发布时间】:2018-05-29 16:31:56
【问题描述】:

我正在一个项目中工作,我需要通过 API 发出请求。这些请求返回有关支持票的数据,但问题是我有大约 500 张票要获取有关数据,每张票都需要一个请求。为了加快请求速度,我尝试构建一个同时生成许多请求的异步例程。但是,由于我正在与之集成的 API 的速率限制器为每秒 10 个请求,因此某些例程会得到“限制超出”的答案。如果我按顺序发出请求,大约需要 5 分钟。

那样,有人在该任务中给我提示吗?我尝试了一些解决方案,例如 NodeJS 的 rate-limiter,但它只是同时生成 10 个请求,并且没有给出任何错误处理,也没有在请求失败时重试。

关于语言,没有限制,项目是用NodeJS编写的,但也有一些python代码,集成其他语言没有问题。

【问题讨论】:

  • 试试setInterval

标签: javascript python node.js api


【解决方案1】:

这样的东西自己创建并不难,它会给你所需的灵活性。

有很多奇特的方法,比如跟踪每个的开始和完成时间,并检查你是否在一秒钟内发送了 10 个。

系统可能还将其限制为 10 个活动请求(即,您不能启动 100 个请求,每秒 10 个,然后让它们全部处理)。

如果您假设这一点,我会说一次启动 10 个,然后让它们完成,然后启动下一批。您也可以启动 10 个,然后每次完成时再启动 1 个。你可以把它想象成“thread pool”。

您可以通过一个简单的变量来跟踪呼叫的数量,从而轻松跟踪这一点。然后,只需检查每秒有多少调用(以避免 1 秒的限制),如果您有可用的“线程”,则触发更多的新请求。

它可能看起来像这样:

const threadLimit = 10;
const rateLimit = 1000; // ms
let activeThreads = 0;

const calls = new Array(100).fill(1).map((_, index) => index); // create an array 0 through 99 just for an example

function run() {
  if (calls.length == 0) {
    console.log('complete');
    return;
  }

  // threadLimit - activeThreads is how many new threads we can start
  for (let i = 0; i < threadLimit - activeThreads && calls.length > 0; i++) {
    activeThreads++; // add a thread
    call(calls.shift())
      .then(done);
  }
  
  setInterval(run, rateLimit);
}

function done(val) {
  console.log(`Done ${val}`);
  activeThreads--; // remove a thread
}

function call(val) {
  console.log(`Starting ${val}`);
  return new Promise(resolve => waitToFinish(resolve, val));
}


// random function to simulate a network call
function waitToFinish(resolve, val) {
  const done = Math.random() < .1; // 10% chance to finish
  done && resolve(val)
  
  if (!done) setInterval(() => waitToFinish(resolve, val), 10);
  
  return done;
}

run();

基本上,run() 会根据限制和已完成的数量启动尽可能多的新线程。然后,它只是每秒重复该过程,尽可能添加新的。

您可能需要使用 threadLimitrateLimit 值,因为大多数速率限制系统实际上并不会让您达到极限,并且不会在完成后立即释放它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-25
    • 2017-12-11
    • 2018-08-07
    • 1970-01-01
    相关资源
    最近更新 更多