👊
【Rails6】Active Job + Sidekiqを動かしてみた
Railsの非同期処理をActive Job + Sidekiqで実装したのでメモを残します。
※RailsアプリケーションはDocker環境で構築済みの前提です。環境構築はこちら。
※Active Jobとバックエンドの比較はこちら。
環境
- Ruby 2.7.2
- Rails 6.0.3.4
- MySQL 8.0.20
- Redis 6.0.9
- Sidekiq 6.1.2
- Docker version 19.03.13
1. Redisの導入
まずredisコンテナを用意します。
ポート番号はdocker-compose.override.yml
で指定していますが、下記で設定して問題ないと思います。
docker-compose.yml
version: '3.7'
services:
db:
image: mysql:8.0.20
volumes:
- mysql:/var/lib/mysql:delegated
command: --default-authentication-plugin=mysql_native_password
env_file: .env
web:
build:
context: .
dockerfile: Dockerfile
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
tty: true
stdin_open: true
env_file: .env
depends_on:
- db
- chrome
- redis
volumes:
- .:/app:cached
- bundle:/usr/local/bundle:delegated
- node_modules:/app/node_modules
chrome:
image: selenium/standalone-chrome:3.141.59
volumes:
- /dev/shm:/dev/shm
redis:
image: redis:6.0.9
env_file: .env
command: redis-server --appendonly yes
volumes:
- redis:/data
volumes:
mysql:
bundle:
node_modules:
redis:
docker-compose.override.yml
version: '3.7'
services:
db:
ports:
- 3306:3306
web:
ports:
- 3000:3000
chrome:
ports:
- 4444:4444
redis:
ports:
- 6379:6379
Redisの設定ファイルを追加します。
host名に注意してください。
config/redis.yml
default: &default
db:
sidekiq: 0
# cache: 1
# session: 2
development:
<<: *default
host: redis
test:
<<: *default
host: redis
2. Sidekiqの設定
まずはGemを追加します。
Gemfile
gem 'sidekiq'
bundle install
を実行し、設定ファイルを追加します。
詳しくは、こちらを参照してください。
config/sidekiq.yml
:verbose: false
:max_retries: 1
:concurrency: 10
:pidfile: ./tmp/pids/sidekiq.pid
:logfile: ./log/sidekiq.log
:queues:
- development_default
続いてSidekiqと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
ダッシュボードのルーティングも設定します。
config/routes.rb
require 'sidekiq/web'
Rails.application.routes.draw do
mount Sidekiq::Web, at: '/admin/sidekiq', as: :sidekiq
end
3. Active Jobの設定
Active Jobで非同期処理を実装していきます。
config/application.rb
require "active_job/railtie"
module App
class Application < Rails::Application
config.active_job.queue_adapter = :sidekiq
config.active_job.queue_name_prefix = Rails.env # これは任意
end
end
4. ジョブの作成と動作確認
ようやくジョブを作成します。
rails g job sample
app/jobs/sample_job.rb
class SampleJob < ApplicationJob
queue_as :default
def perform
puts '--------------------------------'
puts '------------ Test ------------'
puts '--------------------------------'
end
end
続いて動作確認を行います。
dockerコンテナを起動し、RailsとRedisが動いていることを確認します。
コンテナ内でsidekiqを起動します。
$ bundle exec sidekiq -C config/sidekiq.yml
2020-11-23T07:06:57.513Z pid=74 tid=9om INFO: Booting Sidekiq 6.1.2 with redis options {:url=>"redis://redis/0"}
m,
`$b
.ss, $$: .,d$
`$$P,d$P' .,md$P"'
,$$$$$b/md$$$P^'
.d$$$$$$/$$$P'
$$^' `"/$$$' ____ _ _ _ _
$: ,$$: / ___|(_) __| | ___| | _(_) __ _
`b :$$ \___ \| |/ _` |/ _ \ |/ / |/ _` |
$$: ___) | | (_| | __/ <| | (_| |
$$ |____/|_|\__,_|\___|_|\_\_|\__, |
.d$$ |_|
2020-11-23T07:06:57.938Z pid=74 tid=9om INFO: Booted Rails 6.0.3.4 application in development environment
2020-11-23T07:06:57.939Z pid=74 tid=9om INFO: Running in ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]
2020-11-23T07:06:57.939Z pid=74 tid=9om INFO: See LICENSE and the LGPL-3.0 for licensing details.
2020-11-23T07:06:57.939Z pid=74 tid=9om INFO: Upgrade to Sidekiq Pro for more features and support: https://sidekiq.org
2020-11-23T07:06:57.946Z pid=74 tid=9om INFO: Starting processing, hit Ctrl-C to stop
別タブのターミナルでRailsコンソールからSampleJob
をキューイングしてみます。
$ rails c
Loading development environment (Rails 6.0.3.4)
> SampleJob.set(wait: 5.second).perform_later
Enqueued SampleJob (Job ID: fdcf5c60-3542-4b26-bfd2-9662ffafada9) to Sidekiq(development_default) at 2020-11-23 07:08:49 UTC
=> #<SampleJob:0x00005567e535e4c0
@arguments=[],
@exception_executions={},
@executions=0,
@job_id="fdcf5c60-3542-4b26-bfd2-9662ffafada9",
@priority=nil,
@provider_job_id="7c42f602bd499e75efecad26",
@queue_name="development_default",
@scheduled_at=1606115329.3860393>
>
キューイングすると先ほど起動したSidekiq側でジョブが実行されたことが確認できました。
2020-11-23T07:08:52.800Z pid=74 tid=b6y class=SampleJob jid=7c42f602bd499e75efecad26 INFO: start
--------------------------------
------------ Test ------------
--------------------------------
2020-11-23T07:08:53.067Z pid=74 tid=b6y class=SampleJob jid=7c42f602bd499e75efecad26 elapsed=0.267 INFO: done
Discussion