2018年4月10日火曜日

Sidekiq 超入門

概要

Sidekiq はキュー&ワーカー方式で非同期処理を実現するためのツールです
バックエンドに Redis を使っています
今回は動作させるところまでやってみました

環境

  • macOS 10.13.2
  • Ruby 2.4.1p111
  • Redis 3.2.1
  • sidekiq 5.1.3

インストール

  • bundle init
  • vim Gemfile
gem "sidekiq"
  • bundle install --path vendor

Redis も必要になるのでインストールしていない場合は brew などを使ってインストールしてください

ワーカー作成

vim worker.rb

require 'sidekiq'

Sidekiq.configure_server do |config|
  config.redis = { 'db' => 1 }
end

class MyWorker
  include Sidekiq::Worker

  def perform(complexity)
    case complexity
    when 'super_hard'
      sleep 20
      puts 'super_hard'
    when 'hard'
      sleep 10
      puts 'hard'
    else
     sleep 1
     puts 'easy'
    end
  end
end

include Sidekiq::Worker し perform メソッドを実装することでワーカーを作成します
クライアント側でキューイングする際に perform_async を呼び出すことでこの perform メソッドが自動的に呼ばれます

今回は非同期で実行されているか確認できるように sleep を入れています

クライアント作成

  • vim test_client.rb
require './worker.rb'

Sidekiq.configure_client do |config|
  config.redis = { 'db' => 1 }
end

class MyClient
  def enqueue(complexity)
    MyWorker.perform_async(complexity)
  end
end

cli = MyClient.new
cli.enqueue('super_hard')
cli.enqueue('hard')
cli.enqueue('easy')

クライアント側は worker クラスが必要になります
MyWorker クラスでは include Sidekiq::Worker することでエンキュー用の perform_async というメソッドが使えるようになっているのでこれをコールします

今回はワーカー側もクライアント側も localhost:6379 のデフォルトの Redis を参照しているため特にホストやポートの指定はしていませんが、ホストやポートが異なる場合は url というオプションがあるのでそれを使って指定してください (参考)

動作確認

まずはワーカーを起動します
ワーカーは Redis を必要するので Redis も起動しておいてください

  • redis-server
  • mkdir ./tmp
  • bundle exec sidekiq -r ./worker.rb -P ./tmp/sidekiq.pid

sidekiq というコマンドがあるのでこれを使ってワーカースクリプトを指定します
sidekiq コマンドの詳しいオプションは bundle exec sidekiq --help で確認できます
-P オプションで PID ファイルを作成することができます
ワーカーを停止する際に必要になるので指定しておきます
ずらずらーとログが流れてくると思います
キックしている AA とエラーログが流れなければ OK です

次にクライアントを起動します

  • bundle exec ruby test_client.rb

すると以下のようにログが流れると思います

2018-04-04T06:17:54.025Z 4252 TID-oxfu7p3gg MyWorker JID-4473b56c73ed2dd8cf1f89a7 INFO: start
easy
2018-04-04T06:17:55.029Z 4252 TID-oxfu7p3gg MyWorker JID-4473b56c73ed2dd8cf1f89a7 INFO: done: 1.004 sec
hard
2018-04-04T06:18:04.027Z 4252 TID-oxfu7zlbk MyWorker JID-b6be42cf2f3e5f34c7f47468 INFO: done: 10.002 sec
super_hard
2018-04-04T06:18:14.030Z 4252 TID-oxfu7zlh4 MyWorker JID-4ea3461949baefd67e58172c INFO: done: 20.005 sec

enqueue した順番は super_hard -> hard -> easy ですが出力されるのは easy -> hard -> super_hard で表示されており非同期でそれぞれ処理されているのがわかります

ワーカーを停止する場合は sidekiqctl というコマンドが用意されているのでこれを使うと良いです

  • bundle exec sidekiqctl stop ./tmp/sidekiq.pid

PID ファイルを指定すれば停止できます
全部のワーカーが完了するかタイムアウトの 10 秒後の終了します
タイムアウトの時間は設定で変更できます

最後に

SIdekiq の基本的な使い方を紹介しました
Redis を導入する必要はありますが比較的に簡単に導入できるので非同期処理を実現するにはオススメです

Web アプリではよく Rails に組み込む方法が紹介されていますが Sinatra などの軽量フレームワークでも使うことはできます
そのあたりも検証できたら紹介したいと思います

参考サイト

0 件のコメント:

コメントを投稿