Sidekiqをカチャカチャいじってみた
◎前提:検証のためローカルでカチャカチャいじってみただけなので、雑多ですいません。。。
Rails+Redis+Sidekiqの関連図
この図がとてもわかりやすかった
https://dev.icare.jpn.com/dev_cat/sidekiq/
事前準備
ローカルで試す場合こちらを参考に作った
https://qiita.com/yumiyon/items/6835d90e621e73268021
Workerの実装
非同期処理を行うクラスは Sidekiq::Workerを include してつくります。あとは perform メソッドの中に非同期で行いたい処理を書くだけです。引数は自由に追加して OK です。
リトライ回数を5回に設定している
Sidekiq::Workerをincludeしている
class TestWorker < ApplicationController
include Sidekiq::Worker
sidekiq_options queue: :test, retry: 5
def perform(name)
puts 'work: ' + name
end
end
コントローラーにperform_asyncを定義。これが非同期で処理されるジョブです
perform_asyncを使っている(csv出力のジョブなどで)
class HomesController < ApplicationController
def show
TestWorker.perform_async('Hello world')
end
end
以下のgemをインストールした
gem 'sidekiq'
gem 'sinatra', require: false # ダッシュボードを利用するため
gem 'sidekiq-failures' #失敗の処理を管理画面でみれる
gem 'sidekiq-history' #履歴(失敗や成功したジョブ)を管理画面でみれる
gem 'sidekiq-statistic' #ステータスを管理画面でみれる
※redisのgemはデフォルトで入っているが、redisをbrewなどでインストールする必要がある
諸々起動する
- rails起動
- redis起動
- sidekiq起動
管理画面
ジョブを実行する
この Worker は以下のように呼び出します。
TestWorker.perform_async('Hello world')
% rails c
Loading development environment (Rails 7.0.4)
irb(main):001:0> TestWorker.perform_async('Hello world')
2022-12-15T00:04:10.322Z pid=9840 tid=abc INFO: Sidekiq 7.0.2 connecting to Redis with options {:url=>"redis://localhost:6379", :size=>5, :pool_name=>"internal"}
=> "d3fd4c306b8032880ef9eb67"
sidekiqを見てみる
puts 'work: Hello world'
が呼ばれている
管理画面を見てみる
実行前
完了が11
実行後
完了が12で正常に実行されているのがわかる
失敗になる理由
エラーなどでジョブの実行が正常にされなかった時
失敗の数だけ、失敗タブの数が増えます。
待機状態になる理由
sidekiqのプロセスが停止している(sidekiqが起動していない)状態で、ジョブが実行される。そして、redisの中にジョブが積まれている状態になり「待機状態」になる。
(今回のメール送信されない障害はメモリ使用量圧迫によるOMM killerで、sidekiqのプロセスが切られていたことによるもので、結果待機状態にメールのジョブが溜まっていた)
sidekiqをコントロールCで切る
=プロセスが消える
ジョブを実行
TestWorker.perform_async('Hello world')
実行したジョブ(testというキューの中のジョブ)が待機状態になる
(redisの中にジョブが積み上がる)
再度、sidekiqを起動する
→プロセスが立ち上がる
→待機状態のものが再試行にいく→それをまた再試行する→成功にはならない(成功になってほしいのだがならない、、、)
再試行になる理由
ジョブの実行が失敗時に再試行になる
例)
この Worker は以下のように呼び出します。引数を2つ指定してます
TestWorker.perform_async('Hello world', 1)
sidekiqを見てみる
引数が足りないエラーが起きています
管理画面
再試行に1がついている
testのキューにさっき実行した失敗したジョブとエラーメッセージが表示される
再試行を実行する
前提、ジョブの実行に失敗したのが再試行に入るので
管理画面から「今すぐ再試行」しても失敗する(=失敗のカウントが増える)
(もしかしたら方法はあるのかもしれない)
デッドになる理由
リトライ回数(再試行の回数)のMAX(デフォルトのリトライ回数は25回)を達したらデッドに移行する
さっきの失敗したジョブはリトライ5回に設定したので5回を超えるとデッドに移動される
死亡タスクは,sidekiqのダッシュボードからのみ再試行をかけることができる(でも、エラーで死亡しているので再試行しても実行されないはず)
予定になる理由
(例)perform_inメソッドで引数に時間を指定するとsidekiqのキューの「予定」に入ってから1分後にジョブが実行される(どのような時に使うのかわからない)
TestWorker.perform_in(1.minutes, 'Hello world')
予定が1増えている
予定の中(さっき実行したジョブが入っている)
Discussion