現場で 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の概要・特徴・設定・レプリケーションの基礎的な部分を記載しています。※間違…
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などのような非同期処理を行いたい時に使うライブラリです。複数のジョブを同時に実行することにより、メモリを節約すること可能で…
コメント