简体   繁体   English

如何避免因延迟工作而无法满足Heroku的API速率限制

[英]How to avoid meeting Heroku's API rate limit with delayed job and workless

My Survey model has about 2500 instances and I need to apply the set_state method to each instance twice. 我的Survey模型有大约2500个实例,我需要将set_state方法应用于每个实例两次。 I need to apply it the second time only after every instance has had the method applied to it once. 我需要在每个实例都将方法应用于它之后第二次应用它。 (The state of an instance can depend on the state of other instances.) (实例的状态可以取决于其他实例的状态。)

I'm using delayed_job to create delayed jobs and workless to automatically scale up/down my worker dynos as required. 我正在使用delayed_job创建延迟的作业,并且workless无法自动放大/缩小我的工作人员workless

The set_state method typically takes about a second to execute. set_state方法通常需要大约一秒钟才能执行。 So I've run the following at the heroku console: 所以我在heroku控制台上运行以下命令:

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

Shouldn't be any issues with overloading the API, right? 不应该重载API的任何问题,对吗?

And yet I'm still seeing the following in my logs for each delayed job: 然而,我仍然在日志中看到每个延迟工作的以下内容:

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

I'm not seeing any infinite loops -- it just returns this message as soon as I create the delayed job. 我没有看到任何无限循环 - 它只是在我创建延迟作业时立即返回此消息。

How can I avoid blowing Heroku's API rate limits? 如何避免吹Heroku的API速率限制?

Reviewing workless , it looks like it incurs an API call per delayed job to check the worker count and potentially a second API call to scale up/down. 回顾workless ,看起来每个延迟作业都会产生一个API调用,以检查工作人员数量,并可能进行第二次API调用以扩大/缩小。 So if you are running 5000 (2500x2) jobs within a short period, you'll end up with 5000+ API calls. 因此,如果您在短时间内运行5000(2500x2)个作业,您最终将获得5000+ API调用。 Which would be well in excess of the 1200/requests per hour limit. 这将超过1200 /每小时限制请求。 I've commented over there to hopefully help toward reducing the overall API usage ( https://github.com/lostboy/workless/issues/33#issuecomment-20982433 ), but I think we can offer a more specific solution for you. 我在那里发表评论希望有助于减少整体API使用( https://github.com/lostboy/workless/issues/33#issuecomment-20982433 ),但我认为我们可以为您提供更具体的解决方案。

In the mean time, especially if your workload is pretty predictable (like this). 与此同时,特别是如果您的工作量非常可预测(如此)。 I'd recommend skipping workless and doing that portion yourself. 我建议你自己跳过无用的工作。 ie it sounds like you already know WHEN the scaling would need to happen (scale up right before the loop above, scale down right after). 即听起来你已经知道需要进行缩放(在上面的循环之前放大,然后缩小)。 If that is the case you could do something like this to emulate the behavior in workless: 如果是这种情况,你可以做这样的事情来模拟无效的行为:

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)

Note that you'll need to remove workless from these jobs also. 请注意,您还需要从这些作业中删除无效工作。 I didn't see a particular way to do this JUST for certain jobs though, so you might want to ask on that project if you need that. 我没有看到某种特定的方法来为某些工作做这件事,所以如果你需要的话,你可能想问一下这个项目。 Also, if this needs to be 2 pass (the first time through needs to finish before the second), the 4 second sleep may in some cases be insufficient but that is a different can of worms. 此外,如果这需要2次通过(第一次需要在第二次之前完成),4秒睡眠可能在某些情况下是不够的,但这是一种不同的蠕虫。

I hope that helps narrow in on what you needed, but I'm certainly happy to discuss further and/or elaborate on the above as needed. 我希望这有助于缩小您的需求,但我很乐意根据需要进一步讨论和/或详细说明。 Thanks! 谢谢!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM