从 Node.js 向 API 发送许多请求会导致错误

Sending many requests from Node.js to an API causes error

我的数据库中有 2000 多个用户,当我尝试向所有用户广播一条消息时,它只发送了大约 200 个请求,然后我的服务器停止了,我收到如下错误:

{ Error: connect ETIMEDOUT 31.13.88.4:443
at Object.exports._errnoException (util.js:1026:11)
at exports._exceptionWithHostPort (util.js:1049:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1090:14)
code: 'ETIMEDOUT',
errno: 'ETIMEDOUT',
syscall: 'connect,
address: '31.13.88.4',
port: 443 }

有时 我收到另一个错误:

Error!: Error: socket hang up 

这是我的要求:

function callSendAPI(messageData) {
  request({
    uri: 'https://graph.facebook.com/v2.6/me/messages',
    qs: { access_token: '#####' },
    method: 'POST',
    json: messageData

  }, function (error, response, body) {
    if (!error && response.statusCode == 200) {
      var recipientId = body.recipient_id;
      var messageId = body.message_id;

      if (messageId) {
        console.log("Successfully sent message with id %s to recipient %s", 
          messageId, recipientId);
      } else {
      console.log("Successfully called Send API for recipient %s", 
        recipientId);
      }
    } else {
      console.error("Failed calling Send API");
      console.log(error)
    }
  });  
}

我试过了

setTimeout 使 API 呼叫等待一段时间:

 setTimeout(function(){callSendAPI(data)},200);

如果 he/she 遇到类似的错误,有人可以提供帮助吗?

已编辑

我使用的 Messenger 平台支持发送 API 的高调用率,并且不限于 200 次调用。

听起来您达到了速率限制。

来自Facebook documentation

Your app can make 200 calls per hour per user in aggregate.

您可以检查 dashboard 以查看在这些情况下您是否达到了速率限制。

您可能达到了 Facebook API 的限制。要限制请求,您应该在前一个请求的某个时间间隔后发送每个请求。您没有包括迭代所有用户的位置,但我怀疑您可能会循环执行此操作,如果您使用 setTimeout 以 200 毫秒的固定延迟延迟每个请求,那么您将同时完成所有请求与之前一样的时间 - 仅晚 200 毫秒。

您可以做的是:

  1. 您可以使用 setTimeout 并为每个请求添加可变延迟(不推荐)
  2. 您可以使用异步模块的 seriesparallelLimit(使用回调)
  3. 您可以将 Bluebird 的 Promise.mapSeriesPromise.mapconcurrency 限制一起使用(使用承诺)

不推荐使用 1,因为它仍然是即发即弃(除非你增加更多的复杂性)并且你仍然有并发过多和超过限制的风险,因为你只控制何时请求开始,而不是有多少未完成的请求。

2 和 3 大部分相同,但在使用回调或承诺方面有所不同。在您的示例中,您使用的是回调,但您的 callSendAPI 没有自己的回调,如果您希望选项 2 起作用,它应该这样做 - 或者,如果您想要选项,它应该 return 一个承诺3 上班。

有关详细信息,请参阅文档:

当然还有更多方法可以做到,但这些是最直接的。

理想情况下,如果您想充分利用每小时 200 个请求的限制,那么您应该自己对请求进行排队,并按照与该限制相对应的特定时间间隔发出请求。有时,如果您在一个小时内没有执行很多请求,那么您就不需要延迟,但有时您会。您在这里真正应该做的是将所有请求集中排队,并以与已经用完的部分相对应的时间间隔清空队列,达到您应该自己跟踪的限制 - 但这可能很棘手。