我应该如何管理Heroku工人的偶尔工作

时间:2014-12-01 17:17:27

标签: ruby-on-rails ruby-on-rails-4 heroku sidekiq worker-process

我正在处理一个应用程序(部署到Heroku),该应用程序分为公共部分和管理部分。管理部分中的一个主要任务(由少数用户管理)是上传图像。这些图像可能非常大,需要处理为多种尺寸(一些非常大)。我正在处理图像上传客户端,直接上传到S3,然后使用Sidekiq处理图像处理。这样可以避免阻止Web dyno和Unicorn超时问题。

问题在于,这意味着我需要一个工作人员dyno一直在运行,即使管理员通常每天只上传几张图片(尽管他们可能上传很多图片)。我最初的想法是使用Hirefire,但它只检查队列every minute(虽然在我的测试中,它似乎更接近每3分钟)。管理员有一些任务要在处理完图像后完成,所以我需要尽快处理它,所以这种延迟(与处理时间相结合)是不可接受的。

所以我正在寻找能够做到以下几点的解决方案:

  1. 如果需要,只要添加作业,就可以旋转工作人员dyno来处理任何工作。
  2. 队列为空时旋转工作人员dyno。
  3. Hirefire让我到了一半(我不介意延迟击落 dyno)。

    我的选择是什么?

1 个答案:

答案 0 :(得分:0)

希望有人可以拍下来并建议一个更好的方法,但这是一个简单的尝试:

这使用Hirefire在队列为空时将工作人员dyno关闭,并使用heroku-api Gem与Heroku交谈。

初​​始化/ heroku.rb

require 'heroku-api'

if Rails.env.production? || Rails.env.staging?
  Rails.application.config.heroku = Heroku::API.new(api_key: ENV['HEROKU_API_KEY'])
end

应用程序/服务/ heroku_service.rb

require 'heroku-api'

class HerokuService

  def self.ensureWorker
    if Rails.application.config.respond_to? :heroku
      # spawn a worker if needed
      Rails.application.config.heroku.post_ps_scale(ENV['HEROKU_APP_NAME'], 'worker', 1)
    end
  end

end

显然,对Heroku API的调用是阻塞的,并且dyno需要一些时间来启动,但它比单独依赖HireFire快得多。我想知道是否使用调度程序生成一次性dynos,定期检查队列可能比使用Hirefire更好。例如,在晚上10点到早上6点之间不需要监控应用程序。