前言
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/
備註:之後文章修改更新,以個人部落格為主