【问题标题】:How to avoid meeting Heroku's API rate limit with delayed job and workless如何通过延迟工作和无工作来避免满足 Heroku 的 API 速率限制
【发布时间】:2013-07-12 00:47:45
【问题描述】:

我的 Survey 模型有大约 2500 个实例,我需要对每个实例应用 set_state 方法两次。只有在每个实例都应用了一次方法之后,我才需要第二次应用它。 (一个实例的状态可以依赖于其他实例的状态。)

我正在使用 delayed_job 创建延迟作业,并使用 workless 根据需要自动放大/缩小我的工人测功机。

set_state 方法通常需要大约一秒钟的时间来执行。所以我在 heroku 控制台上运行了以下命令:

2.times do
  Survey.all.each do |survey|
    survey.delay.set_state
    sleep(4)
  end
end

重载 API 应该不会有任何问题,对吧?

然而,对于每个延迟的作业,我仍然在日志中看到以下内容:

Heroku::API::Errors::ErrorWithResponse: Expected(200) <=> Actual(429 Unknown)

我没有看到任何无限循环——它只是在我创建延迟作业后立即返回此消息。

如何避免超出 Heroku 的 API 速率限制?

【问题讨论】:

  • 您现在想对每个现有记录执行此set_state 是否正确?为什么不直接从控制台运行它?
  • 是的,我从控制台运行它,但是 Heroku 不喜欢创建 5000 个延迟的作业,事实上,由于 4 秒的延迟,这没有必要。现在在没有“延迟”方法的情况下从控制台运行它,虽然我必须整晚打开控制台,但它似乎工作得很好。干杯。
  • 是的,这就是我的意思!

标签: ruby-on-rails heroku delayed-job


【解决方案1】:

查看workless,看起来它会引发每个延迟作业的 API 调用以检查工作人员数量,并可能会引发第二次 API 调用以扩大/缩小规模。因此,如果您在短时间内运行 5000 (2500x2) 个作业,您最终将获得 5000 多个 API 调用。这将远远超过每小时 1200 个/请求的限制。我在那里发表了评论,希望有助于减少整体 API 使用 (https://github.com/lostboy/workless/issues/33#issuecomment-20982433),但我认为我们可以为您提供更具体的解决方案。

与此同时,尤其是当您的工作量非常可预测时(像这样)。我建议跳过无工作的部分并自己做那部分。即听起来你已经知道何时需要进行缩放(在上面的循环之前放大,之后缩小)。如果是这种情况,你可以做这样的事情来模拟无工作的行为:

require 'heroku-api'
heroku = Heroku::API.new(:api_key => ENV['HEROKU_API_KEY'])

client.post_ps_scale(ENV['APP_NAME'], 'worker', Survey.count)
2.times do
  Survey.all.each do |survey|
    survey.delay.set_state
    sleep(4)
  end
end
min_workers = ENV['WORKLESS_MIN_WORKERS'].present? ? ENV['WORKLESS_MIN_WORKERS'].to_i : 0
client.post_ps_scale(ENV['APP_NAME'], 'worker', min_workers)

请注意,您还需要从这些工作中删除无业者。不过,我没有看到仅针对某些工作执行此操作的特定方法,因此您可能想询问该项目是否需要。此外,如果这需要 2 次通过(第一次通过需要在第二次之前完成),则 4 秒的睡眠在某些情况下可能是不够的,但这是另一回事。

我希望这有助于缩小您的需求,但我当然很乐意根据需要进一步讨论和/或详细说明上述内容。谢谢!

【讨论】:

  • 感谢您的回答,@geemus。但是,据我所知,此处的每个执行块仅在数据库上创建延迟作业。在实际处理工作之前,您的方法不会缩小测功机吗?
  • 是的,再看一遍我认为你是正确的。如果代码是同步的,它会是准确的,但显然不是。更好的方法可能是拥有一个“ScaleDown”工作人员,您可以将其排在其他东西之后。当它运行时,它会检查队列深度并在它很浅时按比例缩小(或者如果它还不是很浅,则重新排队以稍后再试)。我认为这可能会更好地反映这个特定用例的需求。希望对您有所帮助。
猜你喜欢
  • 1970-01-01
  • 2011-08-18
  • 2011-11-14
  • 2014-02-25
  • 2012-04-16
  • 2014-04-03
  • 2020-11-22
  • 2013-05-10
  • 1970-01-01
相关资源
最近更新 更多