配置
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