【Ruby on Rails】sidekiqの導入手順(ローカル、Heroku、AWS EC2、Docker、Capistrano)

AWS Heroku Ruby on Rails

Posted by Yuto Yasunaga at 2020-09-29 20:07:03 +0900

redisを準備する

sidekiqを使う為にredisが必要です。

redisインストール(Mac OS)

brew install redis

redis起動

brew services start redis

docker-composeを使う場合

docker-compose.yml
  redis:
    image: redis:latest
    volumes:
      - redis:/data
    ports:
      - 6379:6379

アプリケーションにsidekiqを導入する

Gemfile
gem 'sidekiq'
config/application.rb
config.active_job.queue_adapter = :sidekiq

sidekiqを起動する

sidekiq -q default -q mailers

もしくは

config/sidekiq.yml
:concurrency: 25
:pidfile: ./tmp/pids/sidekiq.pid
:logfile: ./log/sidekiq.log
:queues:
  - default
  - mailers
:daemon: true
sidekiq -C config/sidekiq.yml

サンプル

アプリケーションには Message というモデルがあり、そのモデルが content と sidekiq_executed_time カラムを持ちます。

例えば、SampleJobを作るとします。

rails g job SampleJob

生成したJobは全ての Message の sidekiq_executed_time を現時点に更新します。

app/jobs/sample_job.rb
class SampleJob < ApplicationJob
  queue_as :default

  def perform(*args)
    sleep(1)
    Message.find_each do |message|
      message.update(sidekiq_executed_time: DateTime.current)
    end
  end
end

コントローラーでは、新規 Message が作成された時に、Jobを非同期実行します。

app/controllers/messages_controller.rb
def create
  @message = Message.new(message_params)
  if @message.save
    redirect_to messages_path, notice: 'Message was successfully created.'
    SampleJob.perform_later
##### 省略 #####

スクリーンショット 0002-08-15 0.14.02.png

実際に新規 Message を作成したら、最初は sidekiq_executed_time がなかったが、数秒後ページをリロードすると値があって、Jobがちゃんと実行されたことが分かります。

スクリーンショット 0002-08-15 0.14.15.png

sidekiqジョブの管理画面

config/routes.rb
require 'sidekiq/web'

Rails.application.routes.draw do
  mount Sidekiq::Web => '/sidekiq'
##### 省略 #####

そして、localhost:3000/sidekiqにアクセスすると管理画面が現れるはずです。

スクリーンショット 0002-08-15 0.20.15.png

Flush Sidekiq's Redis DB

Railsコンソールで
Sidekiq.redis { |r| puts r.flushall }

Herokuで使う

Heroku redisの追加

heroku addons:create heroku-redis:hobby-dev

Heroku redis との接続設定

config/initializes/sidekiq.rb
Sidekiq.configure_server do |config|
  config.redis = { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379') }
end

Sidekiq.configure_client do |config|
  config.redis = { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379')}
end

Procfile の作成

web: bin/rails server -p $PORT -e $RAILS_ENV
worker: bundle exec sidekiq -c 3 -q default -q mailers

デプロイの後、worker dyno を作る

heroku ps:scale web=1 worker=1

AWS EC2で使う

capistrano-sidekiqの設定

Gemfile
gem 'capistrano-sidekiq', require: false, group: :development
Capfile
require 'capistrano/sidekiq'
config/deploy.rb
set :rbenv_map_bins, fetch(:rbenv_map_bins).to_a.concat(%w(rake gem bundle ruby rails puma pumactl sidekiq sidekiqctl))
set :init_system, :systemd

sidekiqがうまく動かない場合

サーバーにアクセスして、sidekiq-production.serviceを修正する

/home/USER/.config/systemd/user/sidekiq-production.service
ExecStart=/home/deploy/.rbenv/shims/bundle exec sidekiq -e production -C config/sidekiq.yml

上の「/home/deploy/.rbenv/shims/bundle」がwhich bundle で確認できたものです。

修正が終わってから、以下のコマンドを実行する

sudo systemctl daemon-reload && systemctl --user reenable sidekiq-production.service && systemctl --user stop sidekiq-production.service && systemctl --user start sidekiq-production.service && sleep 3 && systemctl --user status sidekiq-production.service

sidekiqを再起動する

cap production sidekiq:restart

>>> サンプルアプリケーション


Back