前言
Sidekiq 是 Ruby on Rails 中蠻常用的後台任務處理系統,上篇介紹了 Resque Gem,已知這 2 套 Gem 相比,Sidekiq 的效能比較好...
本身提供的 API 十分簡潔,連 Source Code 也是易於閱讀 (例如這段),Sidekiq 分成 3 種版本 (開源、專業、企業版),欲知差異可到官方網站往下滑便能看到差異比較表,本文以 OSS (Open Source Software) 進行操作
後續的文章會以此 repo 作為範例
如何安裝
放在 Gemfile 檔案中,可參考此 commit
1
2
3
4# Gemfile
gem 'sidekiq', '~> 6.1', '>= 6.1.2'
# 記得要 bundle
加上 Web 介面,可參考此 commit
1
2
3# config/routes.rb
require 'sidekiq/web'
mount Sidekiq::Web => '/sidekiq'
將 ActiveJob 改由 Sidekiq 處理,可參考此 commit
備註: 預設情況下的佇列 (Queue) 的優先順序都為 1
,下方 ['default', 1]
和 ['mailers', 1]
可縮寫成 default
和 mailers
1
2
3
4
5
6
7
8
9
10# config/application.rb
config.active_job.queue_adapter = :sidekiq
# config/sidekiq.yml
:concurrency: 10
:queues:
- ['default', 1]
- ['mailers', 1]
:timeout: 86400
寫個 Worker 確認能否執行
可參考此 commit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38# app/controllers/users_controller.rb
Api::CreateOrderWorker.perform_async(@user.id)
# app/worker/api/create_order_worker.rb
module Api
class CreateOrderWorker
include Sidekiq::Worker
sidekiq_options retry: 7, dead: true, queue: 'create_order_worker'
sidekiq_retry_in { |count| count + 86_400 }
sidekiq_retries_exhausted do |msg, _ex|
subject = "[Api::CreateOrderWorker]Out of retries! #{msg['class']} with #{msg['args']}"
_message = "error: #{msg['error_message']}"
FileLog.logger('worker/api/create_order_worker.log').error(subject)
# ...
end
def perform(user_id)
logger.info "====== start ====== user_id: #{user_id}"
puts 'hello world'
logger.info '====== done ======'
rescue StandardError => e
logger.error "[Api::CreateOrderWorker] ERROR:\n #{e.inspect}\n #{e.backtrace}"
end
private
def logger
FileLog.logger('worker/api/create_order_worker.log')
end
end
end
# config/sidekiq.yml
- ['create_order_worker', 10]
如何執行
終端機輸入
1
2
3sidekiq
# or
bundle exec sidekiq
Sidekiq 啟動成功畫面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23bundle exec sidekiq
m,
`$b
.ss, $$: .,d$
`$$P,d$P' .,md$P"'
,$$$$$b/md$$$P^'
.d$$$$$$/$$$P'
$$^' `"/$$$' ____ _ _ _ _
$: ,$$: / ___|(_) __| | ___| | _(_) __ _
`b :$$ \___ \| |/ _` |/ _ \ |/ / |/ _` |
$$: ___) | | (_| | __/ <| | (_| |
$$ |____/|_|\__,_|\___|_|\_\_|\__, |
.d$$ |_|
2020-09-27T07:58:31.874Z pid=95276 tid=1z4c INFO: Booted Rails 6.0.3.3 application in development environment
2020-09-27T07:58:31.874Z pid=95276 tid=1z4c INFO: Running in ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]
2020-09-27T07:58:31.874Z pid=95276 tid=1z4c INFO: See LICENSE and the LGPL-3.0 for licensing details.
2020-09-27T07:58:31.874Z pid=95276 tid=1z4c INFO: Upgrade to Sidekiq Pro for more features and support: https://sidekiq.org
2020-09-27T07:58:31.874Z pid=95276 tid=1z4c INFO: Booting Sidekiq 6.1.2 with redis options {}
2020-09-27T07:58:31.876Z pid=95276 tid=1z4c INFO: Starting processing, hit Ctrl-C to stop
Sidekiq Web 介面
指定時間執行 Sidekiq
需額外安裝擴充套件 sidekiq-scheduler
Gem,可參考此 commit
備註: 可參考 sidekiq-scheduler GitHub 官方文件
1
2
3
4# Gemfile
gem 'sidekiq-scheduler', '~> 3.0', '>= 3.0.1'
# 記得要 bundle
相關設定及範例如下,可參考此 commit
備註: 對 Cron 不熟悉的話,可看 Wiki 說明,並搭配 Crontab.guru 這網站使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30# config/application.rb
Redis.exists_returns_integer = true
# config/routes.rb
require 'sidekiq-scheduler/web'
# config/sidekiq.yml
- ['scheduler', 5]
:schedule:
CheckWorker:
cron: '30 * * * *'
queue: scheduler
enabled: true
# app/worker/check_worker.rb
class CheckWorker
include Sidekiq::Worker
sidekiq_options retry: 0, queue: 'check_worker'
def perform
puts 'At minute 30.'
end
end
# 這範例是每整點的 30 分,會執行一次 CheckWorker
Sidekiq Recurring Jobs 畫面
更多指令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16sidekiq -h
INFO: sidekiq [options]
-c, --concurrency INT processor threads to use
-d, --daemon Daemonize process
-e, --environment ENV Application environment
-g, --tag TAG Process tag for procline
-q, --queue QUEUE[,WEIGHT] Queues to process with optional weights
-r, --require [PATH|DIR] Location of Rails application with workers or file to require
-t, --timeout NUM Shutdown timeout
-v, --verbose Print more verbose output
-C, --config PATH path to YAML config file
-L, --logfile PATH path to writable logfile
-P, --pidfile PATH path to pidfile
-V, --version Print version and exit
-h, --help Show help
參考資料
小結
Sidekiq 功能非常強大且容易上手,工作上蠻常使用,舉例來說,它的 retry
機制很實用,像打 API 建立訂單,若過程中發生錯誤的話,透過 retry
機制,能重新執行該 job
(能設定 retry
上限、每次間隔時間、超過 retry
上限的話...),並設定 Slack 與 Email 通知 (這部分要自己實作),能即時知道發生異常,進而判斷要如何處理,本身的 Wiki 文件也很完整,且網路上有許多文章、影片 (ex: Youtube 等) 可以參考
鐵人賽文章連結:https://ithelp.ithome.com.tw/articles/10246607
medium 文章連結:https://link.medium.com/RPXFvaCabab
本文同步發布於 小菜的 Blog https://riverye.com/
備註:之後文章修改更新,以個人部落格為主