问题 限制Rails应用程序生成的出站API调用


我不是一个专业的网络开发人员,但我喜欢把网站作为一种业余爱好。最近,我一直在开发一个Rails应用程序作为项目来帮助我学习框架。我的玩具应用程序的目标是通过其API从另一个服务中获取数据,并使我可以使用搜索功能进行查询。

但是,我想从中提取数据的服务对每分钟可执行的API调用数量施加了速率限制。我计划让我的应用程序运行每日更新,这可能会产生一系列API调用,远远超出外部服务提供的限制。我希望尊重外部网站的性能,因此希望限制我的应用程序执行调用的速度。

我已经做了一些搜索,并且我发现了大量的教程资料和预先构建的库来限制 入站 API调用Web应用程序,我几乎找不到控制出站调用流的讨论。

作为一个业余的Web开发人员和铁杆新手,我完全有可能在错误的地方执行错误的搜索。因此我的问题是:

  • 是否有一个很好的网站聚合Rails教程,其中包含与限制出站API请求相关的材料?

  • 是否有任何红宝石宝石或其他库可以帮助我限制请求?

我有一些关于如何使用基于队列的工作程序(如DelayedJob或Resque)编写限制系统来管理API调用的想法,但我宁愿花费我的周末来构建网站的其余部分,如果有一个良好的预先已经建立了解决方案。


10530
2018-05-10 22:35


起源



答案:


没有人谈论出站限制的原因是它通常是非常微不足道的,因为  控制它。控制带宽可能有点难,但控制请求数量?

ri Kernel#sleep

所以,如果你每分钟允许10次api通话,你每次通话后都会睡觉(6)


0
2018-05-10 23:19



是的,这似乎是一个合理的解决方案 - 但我确实有一些问题。 1)需要进行一些微调以使睡眠时间最优化; 2)看起来工作线程在睡眠期间会完全停止。我更喜欢一种解决方案,如果超出呼叫限制而不是挂起,那么工作人员会推迟执行API调用并处理其他任务。 - Sharpie
1)你的意思是什么?你不能比0%的CPU使用效率更高! 2)是的,这就是重点!如果您想要完成其他操作,请将它们提供给另一个线程。我不太明白为什么你似乎如此担心每日批量工作的性能。 *)编辑了关于使用的答案 - user336851
好吧,我想我现在主要担心的是我正在考虑在像Heroku这样的平台上部署应用程序。在这种情况下,我希望进行优化,以便每个线程尽可能高效地完成任务。由于Heroku对每个工人收费,我希望尽可能少地使用工作线程。也许我试图让问题过于复杂......简单的解决方案就是很好的解决方案。 - Sharpie
既然你说你是我唯一认为你会自我托管的用户。我不熟悉heroku但是按绿色线程数收费没有任何意义,因为你一次只能激活一个。所以我认为他们的“工人”实际上是不同的红宝石过程。在那里可以创建许多线程,只有一个线程将受限制调用,其他线程可以执行任何其他操作。如果您不能调用Thread.new并假设没有工作人员启动费,您可以在每次通话后退出工作人员,并在几秒钟之后重新安排对另一名工作人员的下一次通话。 - user336851


答案:


没有人谈论出站限制的原因是它通常是非常微不足道的,因为  控制它。控制带宽可能有点难,但控制请求数量?

ri Kernel#sleep

所以,如果你每分钟允许10次api通话,你每次通话后都会睡觉(6)


0
2018-05-10 23:19



是的,这似乎是一个合理的解决方案 - 但我确实有一些问题。 1)需要进行一些微调以使睡眠时间最优化; 2)看起来工作线程在睡眠期间会完全停止。我更喜欢一种解决方案,如果超出呼叫限制而不是挂起,那么工作人员会推迟执行API调用并处理其他任务。 - Sharpie
1)你的意思是什么?你不能比0%的CPU使用效率更高! 2)是的,这就是重点!如果您想要完成其他操作,请将它们提供给另一个线程。我不太明白为什么你似乎如此担心每日批量工作的性能。 *)编辑了关于使用的答案 - user336851
好吧,我想我现在主要担心的是我正在考虑在像Heroku这样的平台上部署应用程序。在这种情况下,我希望进行优化,以便每个线程尽可能高效地完成任务。由于Heroku对每个工人收费,我希望尽可能少地使用工作线程。也许我试图让问题过于复杂......简单的解决方案就是很好的解决方案。 - Sharpie
既然你说你是我唯一认为你会自我托管的用户。我不熟悉heroku但是按绿色线程数收费没有任何意义,因为你一次只能激活一个。所以我认为他们的“工人”实际上是不同的红宝石过程。在那里可以创建许多线程,只有一个线程将受限制调用,其他线程可以执行任何其他操作。如果您不能调用Thread.new并假设没有工作人员启动费,您可以在每次通话后退出工作人员,并在几秒钟之后重新安排对另一名工作人员的下一次通话。 - user336851


尝试使用nginx作为代理: http://codetunes.com/2011/07/26/outbound-api-rate-limits-the-nginx-way 。

如果你在heroku上,那么考虑使用 慢网 宝石。


8
2017-07-28 19:16





现在有一个宝石: 油门队列。它需要一个代码块,并确保它每秒只执行x次。这是一个从自述文件中获取的示例,它每秒只能获取三个文件:

require 'throttle-queue'

q = ThrottleQueue.new 3
files.each {|file|
    q.background(file) {
        fetch file
    }
}

2
2017-07-20 20:24