
redisを準備する
sidekiqを使う為にredisが必要です。
redisインストール(Mac OS)
redis起動
Copy
1
| brew services start redis
|
docker-composeを使う場合
Copy
docker-compose.yml
1
2
3
4
5
6
| redis:
image: redis:latest
volumes:
- redis:/data
ports:
- '6379:6379'
|
アプリケーションにsidekiqを導入する
Copy
config/application.rb
1
| config.active_job.queue_adapter = :sidekiq
|
sidekiqを起動する
Copy
1
| sidekiq -q default -q mailers
|
もしくは
Copy
config/sidekiq.yml
1
2
3
4
5
6
7
8
9
| :concurrency: 25
:pidfile: ./tmp/pids/sidekiq.pid
:logfile: ./log/sidekiq.log
:queues:
- default
- mailers
- active_storage_analysis
- active_storage_purge
:daemon: true
|
Copy
1
| sidekiq -C config/sidekiq.yml
|
サンプルアプリケーション
アプリケーションには Message
というモデルがあり、そのモデルが content
と sidekiq_executed_time
カラムを持つとします。
例えば、SampleJob
を作ります。
生成したJobは全ての
Message
の
sidekiq_executed_time
を現時点に更新します。
Copy
app/jobs/sample_job.rb
1
2
3
4
5
6
7
8
9
10
| 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を非同期実行します。
Copy
app/controllers/messages_controller.rb
1
2
3
4
5
6
| def create
@message = Message.new(message_params)
if @message.save
redirect_to messages_path, notice: 'Message was successfully created.'
SampleJob.perform_later
##### 省略 #####
|

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

sidekiqジョブの管理画面
Copy
config/routes.rb
1
2
3
4
5
6
7
8
9
10
| require 'sidekiq/web'
Rails.application.routes.draw do
mount Sidekiq::Web => '/sidekiq'
# 認証が必要の場合
Sidekiq::Web.use(Rack::Auth::Basic) do |user, password|
[user, password] == [ENV['SIDEKIQ_USERNAME'], ENV['SIDEKIQ_PASSWORD']]
end
##### 省略 #####
|
そして、localhost:3000/sidekiqにアクセスすると管理画面が現れるはずです。

Flush Sidekiq's Redis DB
Copy
Railsコンソールで
1
| Sidekiq.redis { |r| puts r.flushall }
|
Herokuで使う
Heroku redisの追加
Copy
1
| heroku addons:create heroku-redis:hobby-dev
|
Heroku Redis との接続設定
Copy
config/initializes/sidekiq.rb
1
2
3
4
5
6
7
| 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 の作成
Copy
Procfile
1
2
| web: bin/rails server -p $PORT -e $RAILS_ENV
worker: bundle exec sidekiq -c 3 -q default -q mailers
|
デプロイの後、worker dyno を作る
Copy
1
| heroku ps:scale web=1 worker=1
|
ここまではHerokuの設定が終わり。
AWS EC2で使う
AWS ElastiCache との接続設定
Copy
config/initializes/sidekiq.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| Sidekiq.configure_server do |config|
if Rails.env.production?
redis_conn = proc {
Redis.new(host: ENV['AWS_REDIS_ENDPOINT'], port: 6379, db: 2)
}
config.redis = ConnectionPool.new(size: 27, &redis_conn)
else
config.redis = { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379') }
end
end
Sidekiq.configure_client do |config|
if Rails.env.production?
redis_conn = proc {
Redis.new(host: ENV['AWS_REDIS_ENDPOINT'], port: 6379, db: 2)
}
config.redis = ConnectionPool.new(size: 27, &redis_conn)
else
config.redis = { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379') }
end
end
|
capistrano-sidekiqの設定
Copy
Gemfile
1
| gem 'capistrano-sidekiq', require: false, group: :development
|
Copy
Capfile
1
| require 'capistrano/sidekiq'
|
Copy
config/deploy.rb
1
2
| 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をサーバーにインストールする
Copy
1
| cap production sidekiq:install
|
サーバーにアクセスして、sidekiq-production.serviceを修正する
Copy
/home/USER/.config/systemd/user/sidekiq-production.service
1
| ExecStart=/home/deploy/.rbenv/shims/bundle exec sidekiq -e production -C config/sidekiq.yml
|
上の「/home/deploy/.rbenv/shims/bundle」がwhich bundle
で確認できたものです。
修正が終わってから、以下のコマンドを実行する
Copy
1
| loginctl enable-linger deploy && systemctl --user daemon-reload && systemctl --user stop sidekiq-production.service && systemctl --user daemon-reload && systemctl --user start sidekiq-production.service && systemctl --user enable sidekiq-production.service
|
sidekiqを再起動する
Copy
1
| cap production sidekiq:restart
|
capistrano-sidekiqを使いたくない場合
capistrano-sidekiq
の設定が面倒だったら、別のやり方があります。
同サーバーに複数のアプリケーションを運用する場合は、このやり方をお勧めします。
.serviceファイルを作成する
サーバーでこのようなファイルを作成します。
/etc/systemd/system/sidekiq_<application>_<stage>.service
例えば、アプリ名はmyapp
、production
環境であれば、以下のようになります:
Copy
/etc/systemd/system/sidekiq_myapp_production.service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| [Unit]
Description=sidekiq for myapp (production)
After=syslog.target network.target
[Service]
Type=simple
Environment=RAILS_ENV=production
WorkingDirectory=/deploy/apps/myapp/current
ExecStart=/home/deploy/.rbenv/shims/bundle exec sidekiq -e production -C config/sidekiq.yml
ExecReload=/bin/kill -TSTP $MAINPID
ExecStop=/bin/kill -TERM $MAINPID
RestartSec=1
Restart=on-failure
SyslogIdentifier=sidekiq
[Install]
WantedBy=default.target
|
.serviceファイルを起動する
これを実行すると、sidekiqが起動されます。
Copy
1
| sudo systemctl enable sidekiq_myapp_production.service
|
capistranoのタスクを作成する
capistrano
でデプロイした後で、sidekiqを再起動するためです。
Copy
lib/capistrano/tasks/sidekiq.rake
1
2
3
4
5
6
7
8
9
10
| namespace :sidekiq do
desc 'Restart sidekiq before finishing deployment'
task :restart do
on roles(:app) do
execute "sudo systemctl restart sidekiq_#{fetch(:application)}_#{fetch(:stage)}.service"
end
end
end
before 'deploy:finishing', 'sidekiq:restart'
|
この記事はQiitaのマイページにも掲載しました。
Updated by Yuto at 2023-12-01 06:00