【问题标题】:Background jobs with Resque on Heroku在 Heroku 上使用 Resque 的后台作业
【发布时间】:2016-08-05 09:25:06
【问题描述】:

我在 Heroku 上遇到了一个非常奇怪的问题,我一直在琢磨一段时间。

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

配置/设置

过程文件

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

lib/tasks/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

config/initializers/active_job.rb

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

config/initializers/redis.rb

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

config/initializers/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

问题

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

为什么一种方法可以正常工作而另一种方法不能工作?我已经查看了几乎所有关于该主题的教程/SO 问题,并尝试了所有方法,所以任何帮助让工作运行,但合适的工作人员会很棒!

提前致谢!

【问题讨论】:

    标签: ruby-on-rails heroku resque


    【解决方案1】:

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

    作为参考,所有工作的新的和改进的配置是:

    配置/设置

    过程文件

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

    lib/tasks/resque.rake

    require "resque/tasks"
    
    task "resque:setup" => :environment
    

    config/application.rb

    module App
      class Application < Rails::Application
        ...
    
        # Set Resque as ActiveJob queue adapter.
        config.active_job.queue_adapter = :resque
      end
    end
    

    config/initializers/redis.rb

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

    config/initializers/resque.rb

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

    【讨论】:

    • 似乎这只是因为 Rails 初始化程序是按字母顺序加载的,因此 redis.rbresque.rb 之前加载,所以 $redis 有一个值。我个人去了$redis = Resque.redis = Redis.new(url: ENV["REDISCLOUD_URL"])
    【解决方案2】:

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

    您的 Procfile 中有一个错字。

    应该是resque而不是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(免费)。您也可以从 heroku 上的仪表板执行此操作。

    您可以在 heroku 文档https://devcenter.heroku.com/articles/scaling 上阅读更多相关信息

    【讨论】:

      猜你喜欢
      • 2016-05-29
      • 2023-03-12
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      • 2013-01-10
      • 1970-01-01
      • 2016-07-14
      相关资源
      最近更新 更多