現場で Sidekiq を扱う事になったので、Docker での環境構築と、簡単な使い方を記録します。
Sidekiq とは
Sidekiq は Rails で非同期処理を簡単に行えるようにするための gem です。
使用場面としては以下が考えられます。
- メール通知
- API を叩いて大量のデータを取得
実装
Dockerfile
                    
FROM ruby:2.7.1
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
    && apt-get update -qq \
    && apt-get install -y nodejs yarn chromium-driver shared-mime-info\
    && yarn add chartkick chart.js jquery\
    && mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
                
			docker-compose.yml
Sidekiq は Redis で動かす必要があるため、その設定を行います。
                    
version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - '3306:3306'
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - mysql-data:/var/lib/mysql
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
    stdin_open: true
    tty: true
  chrome:
    image: selenium/standalone-chrome:3.141.59-dubnium
    ports:
      - 4444:4444
  redis:
    image: redis:6.0.9
    env_file: .env
    command: redis-server --appendonly yes
    ports:
      - 6379:6379
volumes:
  mysql-data:
    driver: local
                
			Redis についてはこちらが参考になりました。

【入門】Redis - Qiita
背景現在、自社サービスでRedisを利用していることもあり、あらためて勉強、まとめてみました。今回は、Redisの概要・特徴・設定・レプリケーションの基礎的な部分を記載しています。※間違いなどありましたら、ご指摘いただければ幸いです。Redisの概要こ...
Sidekiq をインストール
                    
gem 'sidekiq'
gem 'sinatra', require: false
                
			bundle install をしてください。
sinatra はダッシュボードを使用するためにインストールします。
Sidekiq 起動時の設定
config/sidekiq.yml
                    
:verbose: false
:pidfile: ./tmp/pids/sidekiq.pid
:logfile: ./log/sidekiq.log
:concurrency: 10
:queues:
  - default
  - test
                
			config/redis.yml
                    
default: &default
  db:
    sidekiq: 0
    # cache:   1
    # session: 2
development:
  <<: *default
  host: redis
test:
  <<: *default
  host: redis
                
			config/initializers/sidekiq.rb
                    
redis_config = YAML.load_file('config/redis.yml')[Rails.env]
redis_config['db'] = redis_config['db']['sidekiq']
Sidekiq.configure_server do |config|
  config.redis = {
    url: "redis://#{redis_config['host']}/#{redis_config['db']}"
  }
end
Sidekiq.configure_client do |config|
  config.redis = {
    url: "redis://#{redis_config['host']}/#{redis_config['db']}"
  }
end
                
			
routes.rb
                    
Rails.application.routes.draw do
  # この2行を追記
  require 'sidekiq/web'
  mount Sidekiq::Web, at: "/sidekiq"
end
                
			アプリケーションを作成
今回はボタンを押したら非同期処理が開始され、元のページにリダイレクトするといった処理を作成していきます。
views/sidekiq_sample/index.html.rb
まずはボタンの作成。
今回は非同期処理を行うジョブに GreetWorker と名付けました。
                    
<%= button_to "GreetWorker を実行", sidekiq_sample_index_path, {method: :post}%>
                
			作成されたボタンはこんな感じ。

controllers/sidekiq_sample_controller.rb
ボタンを押したら create アクションが実行されます。
GreetWorker を30秒後に実行し、引数として”GreetWorker 実行”を渡しています。
                    
class SidekiqSampleController < ApplicationController
  def index
  end
  def create
    GreetWorker.perform_in(30.seconds, "GreetWorker 実行!!!")
    render template: "sidekiq_sample/index"
  end
end
                
			
workers/greet_worker.rb
非同期処理の中身を書いていきましょう。
この非同期処理を行うファイルを Worker と呼び、処理自体のことをジョブと呼びます。
                    
class GreetWorker < ApplicationController
  include Sidekiq::Worker
  sidekiq_options queue: :test, retry: 5
  def perform(string)
    p "#{string}"
  end
end
                
			オプションとして queue, retry を指定しています
- queue … Worker が利用するキューの名前を指定します。デフォルトの値は default
- retry … ジョブが失敗したときに再度行うかを指定します。デフォルトは true ですが、真偽値でなく、回数を指定することも出来ます。
ボタンを3回押してみる
http://localhost:3000/sidekiq/scheduledにアクセス
「予定」のところにジョブが積まれているのがわかります。
Sidekiq を起動していないので、このままでは実行されません。

ちなみに rails console からも確認することが出来ます。
                    
> Sidekiq::ScheduledSet.new.size
=> 3
                
			Sidekiq を起動
                    
$ docker compose exec web bundle exec sidekiq -C config/sidekiq.yml
                
			ターミナルに出力されているのが確認出来ました。
                    
2021-09-27T23:57:35.969Z pid=58 tid=40u INFO: Booting Sidekiq 6.2.2 with redis options {:url=>"redis://redis/0"}
               m,
               `$b
          .ss,  $$:         .,d$
          `$$P,d$P'    .,md$P"'
           ,$$$$$b/md$$$P^'
         .d$$$$$$/$$$P'
         $$^' `"/$$$'       ____  _     _      _    _
         $:     ,$$:       / ___|(_) __| | ___| | _(_) __ _
         `b     :$$        \___ \| |/ _` |/ _ \ |/ / |/ _` |
                $$:         ___) | | (_| |  __/   <| | (_| |
                $$         |____/|_|\__,_|\___|_|\_\_|\__, |
              .d$$                                       |_|
      
2021-09-27T23:57:36.160Z pid=58 tid=40u INFO: Booted Rails 6.1.4.1 application in development environment
2021-09-27T23:57:36.162Z pid=58 tid=40u INFO: Running in ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]
2021-09-27T23:57:36.162Z pid=58 tid=40u INFO: See LICENSE and the LGPL-3.0 for licensing details.
2021-09-27T23:57:36.163Z pid=58 tid=40u INFO: Upgrade to Sidekiq Pro for more features and support: https://sidekiq.org
2021-09-27T23:57:36.172Z pid=58 tid=40u INFO: Starting processing, hit Ctrl-C to stop
2021-09-27T23:57:47.102Z pid=58 tid=cea class=GreetWorker jid=716dd299cef1b681f1a8def5 INFO: start
2021-09-27T23:57:47.245Z pid=58 tid=cj6 class=GreetWorker jid=b813cb60a7ccb23b288cbfa2 INFO: start
2021-09-27T23:57:47.343Z pid=58 tid=ciu class=GreetWorker jid=b91a4066da66578cb7537974 INFO: start
"GreetWorker 実行!!!"
"GreetWorker 実行!!!"
2021-09-27T23:57:47.675Z pid=58 tid=cj6 class=GreetWorker jid=b813cb60a7ccb23b288cbfa2 elapsed=0.426 INFO: done
2021-09-27T23:57:47.675Z pid=58 tid=ciu class=GreetWorker jid=b91a4066da66578cb7537974 elapsed=0.332 INFO: done
"GreetWorker 実行!!!"
2021-09-27T23:57:47.676Z pid=58 tid=cea class=GreetWorker jid=716dd299cef1b681f1a8def5 elapsed=0.574 INFO: done
                
			
その他の参考記事

Railsで非同期処理を行える「Sidekiq」 - Qiita
Sidekiqとは?Sidekiqは、resqueやdelayed_jobなどのような非同期処理を行いたい時に使うライブラリです。複数のジョブを同時に実行することにより、メモリを節約すること可能です。公式リポジトリsidekiqredisをインストールSi...
 
  
  
  
  
コメント