Heroku 上 Resque 的后台作业
Background jobs with Resque on Heroku
我在 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/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
问题
我遇到的问题是,当用户在浏览器中使用该应用程序(即与 Web Worker 交互)并执行触发 ActiveJob 作业之一的操作时,该作业是 运行 "inline" 使用 web
工人而不是 resque
工人。当我 运行 在我的 Heroku 应用程序控制台(由 运行ning heroku run rails console
打开)中对作业进行排队的特定模型方法时,它会将作业添加到 Redis 并使用 运行s resque
工人符合预期。
为什么一种方法可以正常工作而另一种方法不能正常工作?我已经查看了几乎所有关于该主题的教程/SO 问题,并尝试了所有方法,因此任何帮助获得工作的帮助都是 运行,但合适的工人会很棒!
提前致谢!
我稍微调整一下我的配置,设法解决了这个问题。似乎动作是通过 ActiveJob 的 "Inline" 默认值而不是通过 Resque 进行隧道传输的。为了让事情正常进行,我只需要指示 Resque.redis
等于 config/initializers/redis.rb
中设置的 $redis
变量,这样所有内容都指向同一个 Redis 实例,然后移动 [=] 中的配置集18=] 到 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/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"
非常感谢您提供答案。它为我节省了很多时间。
您的 Procfile 中有一个拼写错误。
应该是resque而不是rescue。
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
我在 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/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
问题
我遇到的问题是,当用户在浏览器中使用该应用程序(即与 Web Worker 交互)并执行触发 ActiveJob 作业之一的操作时,该作业是 运行 "inline" 使用 web
工人而不是 resque
工人。当我 运行 在我的 Heroku 应用程序控制台(由 运行ning heroku run rails console
打开)中对作业进行排队的特定模型方法时,它会将作业添加到 Redis 并使用 运行s resque
工人符合预期。
为什么一种方法可以正常工作而另一种方法不能正常工作?我已经查看了几乎所有关于该主题的教程/SO 问题,并尝试了所有方法,因此任何帮助获得工作的帮助都是 运行,但合适的工人会很棒!
提前致谢!
我稍微调整一下我的配置,设法解决了这个问题。似乎动作是通过 ActiveJob 的 "Inline" 默认值而不是通过 Resque 进行隧道传输的。为了让事情正常进行,我只需要指示 Resque.redis
等于 config/initializers/redis.rb
中设置的 $redis
变量,这样所有内容都指向同一个 Redis 实例,然后移动 [=] 中的配置集18=] 到 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/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"
非常感谢您提供答案。它为我节省了很多时间。
您的 Procfile 中有一个拼写错误。
应该是resque而不是rescue。
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