1 分鐘閱讀

前言

Active Job 是rails官方內建的背景執行程序,有adapter可用來連接外部的Sidekiq、resque、delay job等 我個人認為語法滿簡潔的,而且如果以後想改resque或其他也滿好處理 這邊使用sidekiq來執行,並搭配Sidekiq-cron這個plugin來設定排程 並且會安裝Web UI來快速查看執行狀況

說明

sidekiq其實是一個服務,他還搭配了redis這個資料庫

當我們使用sidekiq建立一個排程,其實是建立在redis資料庫中, 如果有安裝sidekiq-corn的話,運作的排程也放在redis

這和我們一般使用whenever建立cron不一樣 whenever建立的cron是放在作業系統(Linux或mac)內建的crontab中,就不用另外啟動其他服務

但使用sidekiq,則一定要確保sidekiq及redis都有運作

前置作業

#####安裝Redis Redis官方網站

安裝 redis 資料庫 $ brew install redis 啟動 redis 資料庫 $ brew services start redis

若需要其他資訊可以輸入 $ brew info redis

#####安裝Sidekiq Sidekiq官方網站

gem 'sidekiq'
gem "sidekiq-cron", "~> 0.4.0"

$ bundle install

第一個Job

1. 新增一個 Active Job
$ rails generate job guests_cleanup

可以發現在 /job 中多了一個 guests_cleanup_job.rb 調整一下perform中輸出的文字

class GuestsCleanupJob < ActiveJob::Base
  queue_as :default
 
  def perform(*args)
    puts 'hello Job!!!'
  end
end

這樣我們就建好一個job了 可以在rails c 中 輸入 GuestsCleanupJob.perform_later 測試,他會把上執行 輸入 GuestsCleanupJob.set(wait_until: Date.tomorrow.noon).perform_later(record) 測試,他會等到明天中午執行 輸入 GuestsCleanupJob.set(wait: 1.week).perform_later(record) 測試,他會等一週後才執行

2. sidekiq

只要加入adapter是sidekiq即可

# [path] application.rb
class Application < Rails::Application
	config.active_job.queue_adapter = :sidekiq
end

加入此行後,之後的原本執行job的指令(如: GuestsCleanupJob.perform_later ),就會丟給sidekiq去執行 記得sidekiq服務要啟動,需要執行 sidekiq

3. sidekiq web UI

加上即可

# [path] route.rb
require 'sidekiq/web'
mount Sidekiq::Web => '/sidekiq'

之後就可以在 http://xxxx/sidekiq 中看到所有job執行狀況

4. sidekiq-cron

sidekiq-cron官方

sidekiq-corn web UI介面 加入 require 'sidekiq/cron/web' 即可 (要在sidekiq/web之後)

# [path] route.rb
require 'sidekiq/web'
require 'sidekiq/cron/web'
mount Sidekiq::Web => '/sidekiq'

官方提供好幾種設定排程方式,這邊介紹兩種:

(1) 直接新增 Sidekiq::Cron::Job.create( name: ‘Hard worker - every 5min’, cron: ‘*/5 * * * *’, class: ‘HardWorker’, active_job: true )

(2) YML ```yml config/schedule.yml my_first_job: cron: “*/5 * * * *” class: “HardWorker” queue: hard_worker active_job: true

second_job: cron: “*/30 * * * *” # 分 時 日 月 週 class: “HardWorker” # 需對應你的Job queue: hard_worker_long # 優先權設定,詳細請看官網說明 active_job: true # 因為我們使用active_job建立,請設為true args: hard: “stuff”

```rb
# [path] config/initializers/sidekiq.rb
schedule_file = "config/schedule.yml"

if File.exists?(schedule_file) && Sidekiq.server?
  Sidekiq::Cron::Job.load_from_hash YAML.load_file(schedule_file)
end

另外如果要跑ActionMail的話,因為預設的queue是mailer 記得要加上sidekiq.yml設定mailers的queue (否則他只會跑default,你的mail就會被一直晾在queue中) ```yml sidekiq.yml — :concurrency: 1 :queues:

  • default
  • mailers ```

記得sidekiq要run

Reference

  1. http://rails.ruby.tw/active_job_basics.html
  2. https://github.com/kakas/Kaohsiung_Rails_Sidekiq_demo

更新時間:

留言