😽

Sidekiqを試す...!

2022/02/21に公開

多分、こういう時に利用する

重い処理がある
定期実行したい処理がある

利用gem

gem 'sidekiq'

利用したいけど、まだ試してないgem等

gem 'sidekiq-rspec' ( 多分、sidekiq の テスト )
gem 'sidekiq-scheduler' ( 多分、定期実行時に使う )
gem 'redis-namespace' ( 多分、redisを共有して複数のnamespaceを利用する場合に利用する )

必要なもの queue の管理(redisなど)

なのでとりあえず枠を用意する。(MySQL定義は・・・一旦使わないけど、ついでに)

  • docker-compose.yml
version: '3'

services:
  db:
    image: mysql:5.7
    volumes:
      - db-volume:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - 3306:3306

  redis:
    image: redis:6.2.6
    volumes:
      - redis-volume:/data
    ports:
      - 6379:6379

volumes:
  db-volume:
  redis-volume:

お試し

rails new rails_sidekiq -d mysql -B --skip-test
  • Gemfile に追加
gem 'sidekiq'
  • install
bundle install
  • sidekiq initializers config ( config/initializers/sidekiq.rb )
    • rails は docker-compose にいれてなく、Mac直なので host redis ではなく、127.0.0.1 を指定している。
    • ついでに sidekiq のログを JSON 形式に。
Sidekiq.configure_server do |config|
  config.redis = { url: 'redis://127.0.0.1:6379' }
  config.log_formatter = Sidekiq::Logger::Formatters::JSON.new
end

Sidekiq.configure_client do |config|
  config.redis = { url: 'redis://127.0.0.1:6379' }
end
  • sidekiq config ( config/sidekiq.yml )
# ログファイル
:logfile: ./log/sidekiq.log
# 同時実行数
:concurrency: 5
staging:
  :concurrency: 10
production:
  :concurrency: 10
# 区分?なんか、 critical にすると default の2倍の速度で確認するとかなんとか。ちゃんと使う時に確認する
:queues:
  - critical
  - default
  - low
  • job generate
rails generate job otameshi
  • job 実行内容 ( app/jobs/otameshi_job.rb )
class OtameshiJob < ApplicationJob
  queue_as :default

  def perform(moziretsu)
    puts 'ここに実行job #{moziretsu}'
    puts "ここに実行job #{moziretsu}"
  end
end
  • sidekiq起動
bundle exec sidekiq
  • job 登録してみる
irb(main):003:0> OtameshiJob.perform_later "文字列"
Enqueued OtameshiJob (Job ID: 21d59bcb-fe45-476a-805e-d6cf702dfe36) to Sidekiq(default) with arguments: "文字列"
=> #<OtameshiJob:0x0000000111271980 @arguments=["文字列"], @exception_executions={}, @executions=0, @job_id="21d59bcb-fe45-476a-805e-d6cf702dfe36", @priority=nil, @provider_job_id="a98ed3c57ad34af70cfab733", @queue_name="default", @successfully_enqueued=true, @timezone="UTC">
  • sidekiq 実行ログ
    • ログ形式についても JSON 形式なってた
{"ts":"2022-02-21T13:23:00.606Z","pid":28529,"tid":"h5x","lvl":"INFO","msg":"start","ctx":{"class":"OtameshiJob","jid":"5297dac07d3cbe42a3114007"}}
{"ts":"2022-02-21T13:23:00.638Z","pid":28529,"tid":"h5x","lvl":"INFO","msg":"Performing OtameshiJob (Job ID: 9aa41bc8-cfc9-4b7c-8a28-8382fd0d5200) from Sidekiq(default) enqueued at 2022-02-21T13:23:00Z with arguments: \"文字列\"","ctx":{"class":"OtameshiJob","jid":"5297dac07d3cbe42a3114007"}}
ここに実行job #{moziretsu}
ここに実行job 文字列
{"ts":"2022-02-21T13:23:00.638Z","pid":28529,"tid":"h5x","lvl":"INFO","msg":"Performed OtameshiJob (Job ID: 9aa41bc8-cfc9-4b7c-8a28-8382fd0d5200) from Sidekiq(default) in 0.75ms","ctx":{"class":"OtameshiJob","jid":"5297dac07d3cbe42a3114007"}}
{"ts":"2022-02-21T13:23:00.639Z","pid":28529,"tid":"h5x","lvl":"INFO","msg":"done","ctx":{"class":"OtameshiJob","jid":"5297dac07d3cbe42a3114007","elapsed":0.033}}

sidekiq 管理画面

  • routes ( config / routes.yml )
require 'sidekiq/web'

Rails.application.routes.draw do
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

  # Defines the root path route ("/")
  # root "articles#index"
  if Rails.env.development?
    mount Sidekiq::Web, at: '/sidekiq'
  end
end
  • rails s して、 /sidekiq にアクセスすると...
    • 実行履歴とかが見える。
    • 未実行 5 については、sidekiqを停止後に rails c からえんきゅーしたもの。
    • それが見えているという事は... sidekiq web は rails s 側で動いてるんだな...!


その他

  • 気になる関連 gem っぽいのも素振りしていきたい。
  • そもそも、 Active job 経由じゃない方法もあるとか、そっちのが主流とかどうなんですかね...?
  • 今まで気にしてなかったけど、重い処理とか、reids溢れたとか、失敗したとか、再実行系が困っちゃうわねぇ...。定期実行ものだったらいいけど、重い処理なのでバックエンドで〜っていう時に、ぷちっと消えた場合どうしてるんだろう? ユーザリクエストをもとに動かしてものとか復元できるんだろうか。実はredisってDBと同じぐらい大事なのでは?(なんか、所詮cacheだしwとか思ってた時期があって申し訳ない)

Discussion