Closed6

Ruby on Rails Background Jobs with Sidekiqのメモ用

ShuSuzukiShuSuzuki

全然sidekiq関係ないけど便利なbin/コマンド
そういえばあんまり自分でいじったことなかった
※foremanは複数のプロセスを管理するためのコマンドラインツール
※Procfile はアプリケーションを構成するプロセスのタイプを宣言するフォーマット

# bin/dev
exec foreman start -f Procfile.dev "$@"
ShuSuzukiShuSuzuki
  • sidkiqで設定しないといけないのはまず4つ
    • redisの接続方法
    • スレッド数(同時実行数)
    • タイムアウトのタイミング
    • キューに関する設定
  • sidekiqの管理画面的なものへのアクセス
    • シンプルなrackApp
    # config/routes.rb
    require "sidekiq/web" 
    mount Sidekiq::Web => "/sidekiq"
    
  • 本だと処理をsidkiqに切り出すときに、jobが処理の中身を知りすぎてはいけないと注意してある
  • sidkiq二処理を切り出すと実行タイミングの問題でテストが落ちることがある
ShuSuzukiShuSuzuki
  • Sidekiqは、ジョブがperform内でキャッチされない例外を発生させた場合、失敗したと見なす
  • Sidekiqは各再試行間の遅延を指数関数的に増加させながら、20日間かけて自動的にジョブを再試行する
  • 永遠に失敗する系はRollbarなり使ってslack通知が基本よね
  • sidekiqのconfigにてerror_handlersという属性を設定するとエラーキャッチャーに接続できる
    • 多分そこにnotify系の処理を置くと通知がいい感じにできる
  • 一時的なエラーと恒久的なエラーの対処を考える必要があり、後者の場合にのみ通知がひつよう
  • ジョブの例外時の設定
    •   Sidekiq.configure_server do |config| config.error_handlers << ->(exception,context_hash) 
      
  • 再試行が終了した場合の設定
    •   config.death_handlers << ->(job,ex) {
      
  • max_retry数にもよるが、上記の組み合わせで一時的(基本通知しない)と恒久的(再試行に失敗したら通知)の対応ができる。
ShuSuzukiShuSuzuki
  • 当たり前だけど冪等性は大事(改めて)
    • jobの冪等性を保っても、jobが依存する箇所が冪等でなかったら意味はない
  • Jobを分割することで、途中の失敗を安全に回収できるが各jobでの微妙な挙動は検知できない(mailジョブでmail送信成功したが、アプリーケーションエラー発生みたいな)
    • mail系のサードパーティだと問い合わせれば送信できたか確認できることもある(これパフォーマンス的にどうなんだ...dbに保存しときたい)
    • keyを数値だけにするとデバックしづらいので"idempotency_key-order-#{order.id}"みたいにしてるらしい
  • 冪等がしっかり確保できない場合はsidekiq_options retry: 0もありらしい(最終手段)
  • テストも冪等性の評価できるものを書きたいよね
  • 理想でいえばjobを1行ずつデバックしながら進めて、再試行時に問題あるところを突き止めるのがよろしいらしい
  • transactionは便利だけど気をつけて使おう
    • transactionの中でjob呼び出しがあると、sidkiqがredisと通信する間ロックがopenしたままになり不安定になることが多い。
ShuSuzukiShuSuzuki
  • sidekiqのver7からはデフォルトで管理画面にメトリクスが表示される
  • sidekiqにはalert用のapiがいくつか用意されている
    • Sidekiq::ProcessSet.new とか便利そう(これが0ならsidekiqが動いていないことになる)
  • Sidekiqのソースコードのlib/sidekiq/api.rbにAPI実装部分がある
    • redisコマンドの重さによってパフォーマンスが調べられる
    • redisの仕様を把握するのも大事よね(redisが死ぬと未実行のjobも失われる)
  • キューに優先順位をつけることも可能
    • queues: hightsidekiq_options queue: "high"を使うみたいな感じ
  • スレッド数を増やして並行で処理できる数を増やすこともできる
  • デフォルトは5
  • リソースの問題もあるので調整が難しい
  • 根本的問題を生む可能性もある(スレッド実行なのでメモリを共有する。クラス変数いじったりすると...)
  • bundle exec sidekiq -q one_at_a_time -c 1 みたいにすると特定のキューだけ処理する新しいプロセスを1つのスレッドで実行できるっぽい?
  • ActiveJobは使うなって言ってる。
 # All jobs use Sidekiq, not Active Job
class ApplicationJob 
include Sidekiq::Worker
end

  • 自身でsidekiqのミドルウェアを作成もできそう
  • railsにはCurrentAttributesとかいうグローバルステートを扱う地雷感ある機能があるらしい
  • perform_bulkで一度に一気にキューにいれることもできる機能があるらしい
このスクラップは2023/11/16にクローズされました