在Heroku上使用Resque进行后台工作

时间:2016-04-14 02:14:58

标签: ruby-on-rails heroku resque

我在Heroku上遇到一个非常奇怪的问题,我现在已经转动了一段时间才弄明白。

我的应用程序有一些外部API调用和邮件,我已将ActiveJob设置为在后台运行。在Heroku上我有两个工作人员设置为,我正在使用Resque / Redis组合来完成以下代码段的工作。我在Heroku上使用Redis Cloud插件。

配置/设置

Procfile

web: bundle exec puma -C config/puma.rb
resque: env TERM_CHILD=1 QUEUE=* bundle exec rake resque:work

LIB /任务/ resque.rake

require "resque/tasks"
require "resque/scheduler/tasks"

task "resque:setup": :environment do
  Resque.before_fork = proc { ActiveRecord::Base.connection.disconnect! }
  Resque.after_fork = proc { ActiveRecord::Base.establish_connection }
end

配置/初始化/ active_job.rb

Rails.application.config.active_job.queue_adapter = :resque

配置/初始化/ redis.rb

if ENV["REDISCLOUD_URL"]
  $redis = Redis.new(url: ENV["REDISCLOUD_URL"])
end

配置/初始化/ resque.rb

if Rails.env.production?
  uri = URI.parse ENV["REDISCLOUD_URL"]
  Resque.redis = Redis.new(host: uri.host, port: uri.port,
                           password: uri.password)
else
  Resque.redis = "localhost:6379"
end

问题

我遇到的问题是当用户在浏览器中使用应用程序(即与Web工作者连接)并执行一个动作,触发其中一个ActiveJob作业时,作业使用{{1“内联”运行工人而不是web工人。当我运行在我的Heroku应用程序控制台中排队作业的特定模型方法(通过运行resque打开)时,它将作业添加到Redis并按预期使用heroku run rails console工作程序运行它。

为什么一种方式正常工作而另一种方式不起作用?我已经查看了关于该主题的几乎每个教程/ SO问题,并且已经尝试了所有内容,因此任何有助于运行工作的帮助,但合适的工作人员会很棒!

提前致谢!

2 个答案:

答案 0 :(得分:3)

我设法通过稍微玩配置来解决问题。似乎行动是通过ActiveJob的“内联”默认而不是通过Resque进行挖掘的。为了使工作正常,我只需将Resque.redis指向等于$redis中设置的config/initializers/redis.rb变量,这样所有内容都指向同一个Redis实例,然后移动config/initializers/active_job.rb中的配置集。 1}}到application.rb

供参考,新的&所有工作的改进配置是:

配置/设置

<强> Procfile

web: bundle exec puma -C config/puma.rb
resque: env TERM_CHILD=1 RESQUE_TERM_TIMEOUT=7 QUEUE=* bundle exec rake resque:work

<强> LIB /任务/ resque.rake

require "resque/tasks"

task "resque:setup" => :environment

<强>配置/ application.rb中

module App
  class Application < Rails::Application
    ...

    # Set Resque as ActiveJob queue adapter.
    config.active_job.queue_adapter = :resque
  end
end

<强>配置/初始化/ redis.rb

if ENV["REDISCLOUD_URL"]
  $redis = Redis.new(url: ENV["REDISCLOUD_URL"])
end

<强>配置/初始化/ resque.rb

Resque.redis = Rails.env.production? ? $redis : "localhost:6379"

答案 1 :(得分:3)

非常感谢您提供答案。它为我节省了很多时间。

你的Procfile中有一个拼写错误。

它应该是resque而不是救援。

resque: env TERM_CHILD=1 RESQUE_TERM_TIMEOUT=7 QUEUE=* bundle exec rake resque:work

另外,我不得不输入一个命令来让这一切都在生产中工作。希望这有助于某人。

heroku ps:scale resque=1 --app appname

此命令将resque进程缩放为1 dyno(free)。您也可以通过heroku上的仪表板执行此操作。

您可以在heroku docs https://devcenter.heroku.com/articles/scaling

上阅读更多相关信息