delay_job 更新查询无限运行
Posted
技术标签:
【中文标题】delay_job 更新查询无限运行【英文标题】:delayed_job update query is running infinitely 【发布时间】:2013-04-08 15:43:39 【问题描述】:我在我的 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 计数为零。正因为如此,应用程序非常慢,并且页面在很多地方都没有加载。
【问题讨论】:
关心尝试delayed_job_active_record_threaded 并看到这有帮助吗?我很想听听您的反馈 =) github.com/zxiest/delayed_job_active_record_threaded 这里也一样。这是骗人的,因为没有工作,它也试图做一个UPDATE
。只会在日志中产生很多不必要的噪音。
@Menon 你找到解决方案了吗?
【参考方案1】:
我遇到了同样的问题,我通过在队列字段上添加索引来解决它。
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/
【讨论】:
【参考方案2】:我必须使用 AR 的 silence
方法,只需在文件 [path/to/delayed_job_active_record/gem]/delayed_job_active_record-[any.latest.version]/lib/delayed/backend/active_record.rb
的第 68 行附近更改:
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
中覆盖它
【讨论】:
【参考方案3】:我认为您的意思是 delayed_job
轮询过于频繁(顺便说一下,默认情况下是每 5
秒)-我知道这会填满您的日志,并且 似乎“无限”.. :)
如果这就是你的意思,那么我建议你运行workless gem。它只会根据需要启动delayed_job
。许多人使用它来防止他们的Heroku worker 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'
如果您需要更多指导,请在下面的 cmets 中告诉我。
【讨论】:
【参考方案4】:所以这是一个专门为 Postgres 设计的查询。请参阅https://github.com/collectiveidea/delayed_job_active_record/blob/master/lib/delayed/backend/active_record.rb#L57 了解为什么必须这样。
延迟作业的想法确实是它会定期查询数据库,因此只要工作人员正在运行,您的问题中的查询就会被触发。这应该每秒发生一次,我无法想象这会对您的应用程序的性能产生重大影响。
您是否在非常有限的硬件上运行,例如非常小的虚拟机?
【讨论】:
不是虚拟机。亚马逊的小例子。而且我使用的是 mysql 而不是 postgres。 我明白了,也许它很慢,因为它正在交换到磁盘?你检查过 ruby 进程的内存占用吗?以上是关于delay_job 更新查询无限运行的主要内容,如果未能解决你的问题,请参考以下文章