這個 Demo 使用
ruby 2.2.0
rails 4.2.3
$
表示要在命令列輸入指令
- 安裝 redis 資料庫,
$ brew install redis
- 啟動 redis 資料庫,
$ brew services start redis
- 若需要其他資訊可以輸入,
$ brew info redis
官方網站: mperham/sidekiq: Simple, efficient background processing for Ruby
gem 'sidekiq'
$ bundle install
- 增加 workers 資料夾及測試用 worker,
app/workers/my_test_worker.rb
- 記得 worker.rb 要存檔
class MyTestWorker
include Sidekiq::Worker
def perform
puts "do something"
end
end
- 在 iterm 開一個新的 tab 輸入
$ sidekiq
,啟動 sidekiq 伺服器 - 再開一個 tab,輸入
$ rails console
- 增加工作給 sidekiq,
> MyTestWorker.perform_async
- 如下所示,sidekiq server 有印出
do something
表示成功
PS:如果出現NameError: uninitialized constant xxxxxxxxxxx
除了你打錯字以外,也可能是 spring cache 機制卡住了
試試看執行 $ spring restart
再重開 rails console 試試看。
Loading development environment (Rails 4.2.3)
2.2.0 :001 > MyTestWorker.perform_async
=> "c5627145a59889bca376c69c"
2016-07-07T03:08:50.466Z 22213 TID-ov8zu6vu0 MyTestWorker JID-c5627145a59889bca376c69c INFO: start
do something
2016-07-07T03:08:50.467Z 22213 TID-ov8zu6vu0 MyTestWorker JID-c5627145a59889bca376c69c INFO: done: 0.0 sec
官網教學連結:Monitoring · mperham/sidekiq Wiki,可以對照著看
gem 'sinatra', :require => false
,(PS:rails 5.0.0 要改成gem 'sinatra', github: 'sinatra'
)$ bundle install
- 修改
routes.rb
require 'sidekiq/web'
Rails.application.routes.draw do
mount Sidekiq::Web => '/sidekiq' # 可以隨意指定,譬如 '/QQ/sidekiq' 也可以
end
- 關閉 sidekiq server。(PS:到 sidekiq server 的 tab 按
ctrl + c
即可把 sidekiq server 關閉) - 開新 tab 啟動 rails server,
$ rails s
- 網址輸入你剛剛設定的位址,譬如:
http://localhost:3000/sidekiq
- 進去後如果有看到很炫炮的 sidekiq 後台表示成功。示意圖
- 測試:進
rails console
增加幾個 worker、檢查 Web UI Enqueued 數量是否增加、啟動 sidekiq server,自行發揮。
cron job 教學:cron jobs 的使用
官網連結:ondrejbartas/sidekiq-cron: Scheduler / Cron for Sidekiq jobs
gem 'sidekiq-cron'
$ bundle install
- 增加
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
- 增加並設定
config/schedule.yml
sidekiq_demo_job:
cron: "*/1 * * * *"
class: "MyTestWorker" # 需對應到你的 worker
queue: default # 優先權設定,詳細請看官網說明
- 在
routes.rb
的require 'sidekiq/web'
下面加上require 'sidekiq/cron/web'
- 重開 sidekiq 及 rails server,檢查 sidekiq Web UI,應該會在上方增加一個
Cron
的按鈕 - 因為在你的電腦每個專案的 sidekiq 都會使用同一個 redis,所以如果你之前有用過 sidekiq-cron,可能會在 Web UI 的 Cron 裡面發現之前的 worker,請先把它們刪除再測試,不然在 sidekiq server 會出現找不到 worker 的錯誤。
- 在 Cron 的 UI 裡面有一個
EnqueueNow
的按鈕可以手動執行 Worker ,可以很方便的測試 Cron job - 自己測看看吧。
假設我們有一個 Product Model,擁有 title 跟 image 這兩個欄位,當使用者增加 product 時 可以上傳一張圖片,Server 會將這張圖片壓縮成指定的大小,不過不可能讓使用者等待圖片壓縮完成後才能繼續瀏覽網頁,這樣會讓使用者體驗很差,因此我們要增加一個背景工作讓 Server 有空的時候可以執行這項任務。
$ rails g scaffold product title image
$ rake db:migrate
- 增加一個圖片壓縮的 worker
workers/image_compress_worker.rb
class ImageCompressWorker
include Sidekiq::Worker
def perform(product_id)
@product = Product.find(product_id)
puts "執行#{@product.title}的圖片壓縮工作"
puts "#{@product.title}的圖片壓縮工作已經完成"
end
end
- 當新增或修改產品後自動增加圖片壓縮的 worker
models/product.rb
class Product < ActiveRecord::Base
after_commit :compress_image
def compress_image
ImageCompressWorker.perform_async(id)
end
end
- 請自行測試,記得每次改完 worker 後要重開 sidekiq server
- 另外,沒辦法傳 ActiveRecord 的物件給 worker,所以這邊只能傳 product 的 id 給worker,如果你想傳 ActiveRecord 的物件,可以試試看用 ActiveJob(Active Job · mperham/sidekiq Wiki)