自分用メモ
ActiveJob経由か、直接使うかは
以下の記事で詳細を書いた。
thoames.hatenadiary.jp
自分の場合は、フルにSidekiqの機能を使用したかったため
「直接Sidekiqを使用する」方法を取る。
インストール
Gemfile
gem 'sidekiq'
gem 'redis-namespace'
[注意] Redisの設定にnamespaceを設定している場合、
'redis-namespace'のgemをインストールしていいないと、
以下のエラーが出る。
ERROR: Your Redis configuration uses the namespace 'xxxxxxxxx'
but the redis-namespace gem is not included in the Gemfile.
Add the gem to your Gemfile to continue using a namespace.
Otherwise, remove the namespace parameter.
[参考]
Sidekiq - DesignAssembler
実行
設定ファイルを読み込んで起動する場合
$ bundle exec sidekiq -C config/sidekiq.yml
ベストプラクティス
以下のようにオブジェクトを渡した後、キューが実行される前に
そのオブジェクトが変わった場合、
意図したものと違う内容が実行されてしまう可能性がある。
またRedisにデータを保存する時、引数の情報がJSONとして保存される。
(内部ではRedisに保存するときに、JSON.dumpを使用し、
Redisからデータを参照するときにJSON.loadを使用している)
このため、perform_asyncに渡す引数は必ずJSONとして保存できる
「string, integer, float, boolean, null, array and hash」のいずれかでなければならない。
シンボルやオブジェクト(dateやtimeなども)は引数にしてはいけない。
そのため、処理を特定できる識別子(IDなど)を引数として設定し、
キュー処理の内部で、IDを用い処理を行うことが推奨されている。
✕: 悪い例
quote = Quote.find(quote_id)
SomeWorker.perform_async(quote)
○: 良い例
SomeWorker.perform_async(quote_id)
Best Practices · mperham/sidekiq Wiki · GitHub
バックトレース
例外発生時に、その例外のbacktraceログも残したい場合は以下の設定を行う。
sidekiq_options backtrace: true
ただし、大量にJOBが失敗するなど、かなりのbacktraceログが発生する可能性がある場合は
Redisに割り当てるメモリを増やすか、backtraceログの出力行を設定する。
出力行は上から数えた行数を設定する。
例)上から20行までを出力する設定
sidekiq_options backtrace: 20
各workerに設定したくない場合はsidekiq.rbに以下のように設定すれば
全体に設定される。
config/initializers/sidekiq.rb
...
Sidekiq.default_worker_options = { 'backtrace' => true }
Sidekiq.default_worker_options = { 'backtrace' => 20 }
...
死亡直前のログ出力
各workerで設定する場合
...
include Sidekiq::Worker
sidekiq_retries_exhausted do |msg, e|
Sidekiq.logger.warn "Failed #{msg['class']} with #{msg['args']}: #{msg['error_message']}"
end
...
一括で設定する場合(config/initializers/sidekiq.rb)
Sidekiq.configure_server do |config|
config.default_retries_exhausted = -> (job, ex) do
Sidekiq.logger.warn "#{job['class']} job is now dead: args(#{job['args']}) => msg(#{job['error_message']})"
end
end
[参考]
Sidekiq で最大回数リトライ後に失敗した場合出すログに例外のバックトレースを含める - Qiita
死亡時にSlack通知
Slack通知にはslack-notifierを使用する。
詳細は以下のページが詳しい。
slack-notifierでrailsからSlackへ簡単にメッセージを送る - Qiita
config.default_retries_exhausted内に設定を追記すれば良い。
config.default_retries_exhausted = -> (job, ex) do
message = "#{job['class']} job is now dead: args(#{job['args']}) => msg(#{job['error_message']})"
Slack::Notifier.new(Settings[:sidekiq][:slack_notifier_url]).ping(message)
Sidekiq.logger.warn message
end
ベーシック認証
require 'sidekiq/web'
Sidekiq::Web.use Rack::Auth::Basic do |username, password|
username == 'basicuser' && password == 'basicpass'
end
mount Sidekiq::Web => '/sidekiq'