1

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

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

因此,我正在寻找执行以下操作的解决方案:

  1. 如果需要,只要添加工作,就可以启动工人测功机来处理任何工作。
  2. 当队列为空时,关闭工作人员测功机。

Hirefire 让我走到了一半(我不介意延迟旋转测功机)。

我有哪些选择?

4

1 回答 1

0

希望有人可以将其击落并提出更好的方法,但这里有一个简单的尝试:

当队列为空时,它使用 Hirefire 将 worker dyno 关闭,并使用heroku-apiGem 与 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 快得多。我想知道是否使用调度程序生成一次性的测功机以定期检查队列可能比使用 Hirefire 更可取。例如,没有必要在晚上 10 点到早上 6 点之间监控应用程序。

于 2014-12-01T18:50:57.487 回答