我在rails应用程序中使用delayed_job和delayed_job_active_record来执行后台作业。我们正在使用基于队列的delayed_job。为了启动延迟,我使用以下命令。
RAILS_ENV=staging script/delayed_job -i=1 --queue=queue_name start
问题是下面的查询是无限制的。
SQL (0.4ms) UPDATE `delayed_jobs` SET `locked_at` = '2013-04-16 09:27:23', `locked_by` = 'delayed_job.=2 host:ip-10-204-210-77 pid:2168' WHERE `delayed_jobs`.`queue` IN ('queue_name') AND ((run_at <= '2013-04-16 09:27:23' AND (locked_at IS NULL OR locked_at < '2013-04-16 05:27:23') OR locked_by = 'delayed_job.=2 host:ip-10-204-210-77 pid:2168') AND failed_at IS NULL) ORDER BY priority ASC, run_at ASC LIMIT 1
delayed_job计数为零。因此,应用程序非常慢,页面不会在很多地方加载。
答案 0 :(得分:4)
我认为你的意思是delayed_job
过于频繁地进行民意调查(顺便提一下,默认情况下每隔5
秒) - 我知道这会填满你的日志,和似乎“无限”.. :))
如果这就是您的意思,那么我建议您运行workless gem。它只会根据需要启动delayed_job
。很多人用它来让Heroku工作人员的dynos无法闲置,但它在development
模式下同样有效。
请注意,如果您使用的是delayed_job_active_record,则还需要将gem 'daemons'
添加到Gemfile
(daemons)。请参阅Running Jobs section of delayed_job
。
因此,您的Gemfile
将包含:
gem 'delayed_job_active_record'
gem 'daemons'
gem 'workless'
如果您需要更多指导,请在下面的评论中告诉我们。
答案 1 :(得分:2)
我必须使用AR的silence
方法,只需在第68行更改文件[path/to/delayed_job_active_record/gem]/delayed_job_active_record-[any.latest.version]/lib/delayed/backend/active_record.rb
:
count = ready_scope.limit(1).update_all(:locked_at => now, :locked_by => worker.name)
到
count = silence {ready_scope.limit(1).update_all(:locked_at => now, :locked_by => worker.name)}
肮脏的解决方案,我知道,但是它有效...欢迎提出一个更好的包装器,但对我来说Job.reserve
方法有足够大的力量来消除任何想法,以便在config/initializers
中覆盖它
答案 2 :(得分:1)
所以这是专为Postgres设计的查询。请参考https://github.com/collectiveidea/delayed_job_active_record/blob/master/lib/delayed/backend/active_record.rb#L57了解为何必须如此。
延迟作业的想法确实会定期查询数据库,因此只要工作程序正在运行,您的问题中的查询就会被解雇。这应该每秒发生一次,我无法想象这会对您的应用程序的性能产生重大影响。
您是否在非常有限的硬件上运行,如非常小的虚拟机?
答案 3 :(得分:0)
我遇到了同样的问题,我通过在队列字段上添加索引来解决了这个问题。
def self.up
create_table :delayed_jobs, :force => true do |table|
# Add index on queue field
add_index :delayed_jobs, [:queue], :name => 'delayed_jobs_queue'
end
有关更多信息,请访问下面的文档http://himarsh.org/cautions-on-delayed-jobs/