Sidekiqでメールと重処理
Ruby応用でジョブ管理を始める
Ruby on Rails でのジョブ管理は、バックグラウンドで実行したい処理を分離し、ユーザー体験を向上させるために不可欠です。まずはジョブ管理の基本概念を押さえ、ActiveJob を使ってジョブを定義します。ActiveJob は Rails 標準のジョブフレームワークで、複数のバックエンド(Sidekiq、Resque、DelayedJob など)に対応しています。
ジョブは app/jobs ディレクトリに作成し、perform メソッドに処理を記述します。以下は簡単な例です。
class SampleJob < ApplicationJob
queue_as :default
def perform(user_id)
user = User.find(user_id)
# 何らかの処理
end
end
このジョブを呼び出すには SampleJob.perform_later(user.id) を使用します。ジョブは非同期でキューに投入され、バックエンドが実行します。
ActiveJobとSidekiqの連携
Sidekiq は Redis をバックエンドに持つ高速なジョブキューです。ActiveJob と Sidekiq を組み合わせることで、Rails アプリケーションのジョブ管理をシームレスに行えます。Gemfile に sidekiq を追加し、設定ファイルで config.active_job.queue_adapter = :sidekiq を指定します。
# Gemfile
gem 'sidekiq'
# config/application.rb
config.active_job.queue_adapter = :sidekiq
Sidekiq は config/sidekiq.yml で設定可能で、ジョブの優先度やレート制限を細かく制御できます。ジョブを Sidekiq で実行する際は、bundle exec sidekiq -C config/sidekiq.yml を起動します。
Redisを使ったキュー管理
Sidekiq のキューは Redis に保存されます。Redis は高速なインメモリデータストアで、ジョブの永続化とスケジューリングに最適です。Redis の設定は config/redis.yml で行い、環境ごとに接続情報を分離します。
# config/redis.yml
development:
url: redis://localhost:6379/0
production:
url: redis://<%= ENV['REDIS_URL'] %>
Redis のデータ構造はリスト(list)を使用し、ジョブは FIFO で処理されます。Sidekiq は Redis の BLPOP コマンドでジョブを取得し、非同期で実行します。
非同期処理でメール送信を高速化
メール送信はネットワーク遅延が発生しやすく、同期処理だとユーザー待ち時間が増大します。ジョブを使ってメール送信を非同期化することで、レスポンスを即座に返せます。Rails では ActionMailer と ActiveJob を組み合わせて簡単に実装できます。
# app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer
def welcome_email(user)
@user = user
mail(to: @user.email, subject: 'Welcome!')
end
end
# app/jobs/welcome_email_job.rb
class WelcomeEmailJob < ApplicationJob
queue_as :mailers
def perform(user_id)
user = User.find(user_id)
UserMailer.welcome_email(user).deliver_later
end
end
このようにジョブを作成し、WelcomeEmailJob.perform_later(user.id) でメール送信をバックグラウンド化します。Sidekiq がメール送信ジョブを処理し、ユーザーは即座に次の画面へ遷移できます。
重い処理のバックグラウンド化のベストプラクティス
重い処理(画像変換、データ集計、外部 API 呼び出しなど)は、ジョブとして切り出すことでスケーラビリティを確保します。以下にベストプラクティスをまとめます。
- ジョブは小さく、単一責任にする。
- ジョブの再試行はデフォルトで有効にし、失敗時に自動で再実行。
- ジョブの優先度を設定し、重要度に応じてキューを分ける。
- ジョブの実行時間を監視し、長時間実行されるジョブは分割。
- Sidekiq のプロセス数を環境に合わせてスケールアウト。
これらを実践することで、Ruby アプリケーションは高負荷時でも安定したレスポンスを維持できます。
コメント
コメントを投稿