配置
STEP 1
如果使用数据库存储任务队列,在Gemfile中加入
gem 'delayed_job_active_record'
然后执行
bundle install
STEP 2
生成delayed_job需要的文件
rails generate delayed_job:active_record
执行迁移文件(或手动建表delayed_jobs)
rails db:migrate
在config/application.rb
中配置
config.active_job.queue_adapter = :delayed_job
配置config/initializers/delayed_job_config.rb
Delayed::Worker.destroy_failed_jobs = false
Delayed::Worker.sleep_delay = 60
Delayed::Worker.max_attempts = 3
Delayed::Worker.max_run_time = 5.minutes
Delayed::Worker.read_ahead = 10
Delayed::Worker.default_queue_name = ‘default’
Delayed::Worker.delay_jobs = !Rails.env.test?
Delayed::Worker.raise_signal_exceptions = :term
Delayed::Worker.logger = Logger.new(Rails.configuration.log_root + 'delayed_job.log')
STEP 3
启动任务处理器
如果是development环境可以用如下方式:
前台运行的worker线程,会直接在terminal打印log
rake jobs:work
如果是线上环境,最好使用脚本启动方式,这会监控jobs的进程,并且允许后台运行多个线程
后台开始/关闭worker线程
RAILS_ENV=production bin/delayed_job start
RAILS_ENV=production bin/delayed_job stop
STEP 4
在Controller中只需要在对象或类方法名前加入 .delay(run_at: 1.minutes.from_now).method()
,就可以让该线程运行在后台
使用示例
亲测似乎只能在model和controller中使用,在util中使用一直失败
### Call .delay.method(params) on any object and it will be processed in the background.
# without delayed_job
@user.activate!(@device)
# with delayed_job
@user.delay.activate!(@device)
### If a method should always be run in the background, you can call #handle_asynchronously after the method declaration:
class Device
def deliver
# long running method
end
handle_asynchronously :deliver, :run_at => 5.minutes.from_now, :priority => 0, :queue => "default"
end
device = Device.new
device.deliver
handle_asynchronously
和 delay
方法支持如下参数
- :priority (number): 越小优先级越高,默认为0
- :run_at (Time): 多久以后执行该job
- :queue (string): 指定要将该job放到哪个队里里
命令
#前台运行的worker线程,会直接在terminal打印log
rake jobs:work
#后台开始/重启/关闭worker线程
RAILS_ENV=production bin/delayed_job start
RAILS_ENV=production bin/delayed_job restart
RAILS_ENV=production bin/delayed_job stop
#处理[某个队列]所有任务后退出
rake jobs:workoff
QUEUE=tracking rake jobs:work
#删除所有jobs
rake jobs:clear
问题
- 存在delayed_jobs表里的时间都是UTC的,也就是比北京时间提前了8小时,怎么调整?
答:没有找到合适的方法,如果设置config/application
config.time_zone = 'Beijing'
config.active_record.default_timezone = 'Beijing'
则存到表里的时间为北京时间,但是delayed_job似乎还是要等到UTC时间走到表中的时间才会执行
- log怎么看
答:在表中可以看注册但没执行的任务,参数、时间、尝试次数等
log可以在config/initializers/delayed_job_config.rb
中配置
参考
4 Simple Steps to Implement “Delayed Job” in Rails
https://github.com/collectiveidea/delayed_job
网友评论