0

我的调查模型有大约 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 速率限制?

4

1 回答 1

2

回顾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 秒的睡眠在某些情况下可能是不够的,但这是另一回事。

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

于 2013-07-15T16:50:51.387 回答