Sidekiqって何?
Webアプリを使っていると、こんな場面があります。
- 会員登録したらウェルカムメールを送る
- 画像をアップロードしたらサムネイルを生成する
- 大量のデータをCSVに書き出す
これらをユーザーが待っている間にやろうとすると、画面がフリーズしたように見えてしまいます。
そこで登場するのが Sidekiq(サイドキック) です。
Sidekiqは、時間のかかる処理を「あとでやっておくね」と裏側に回してくれるライブラリです。ユーザーは待たされることなく、バックグラウンドで処理が進んでいきます。
非同期処理ってどういうこと?
少し整理しておきましょう。
同期処理(普通の処理)
ユーザーがボタンを押す
↓
メールを送る(数秒かかる)
↓
「完了しました」と画面に表示される
ユーザーはメールが送り終わるまでずっと待つ必要があります。
非同期処理(Sidekiqを使った場合)
ユーザーがボタンを押す
↓
「メールを後で送っておいて」とSidekiqに依頼
↓
すぐに「完了しました」と画面に表示される
↓(裏側で)
Sidekiqがメールを送る
ユーザーはすぐに次の操作に移れます。
Sidekiqの仕組みをざっくり理解する
Sidekiqは大きく3つの要素で成り立っています。
1. ジョブ(Worker)
「何をやるか」を書いたクラスです。メールを送る、画像を変換するなど、実際の処理をここに書きます。
2. キュー(Queue)
ジョブの「待ち列」です。依頼されたジョブは一旦ここに並びます。
3. Redis(レディス)
キューを保存しておくためのデータストアです。SidekiqはこのRedisを使ってジョブを管理しています。
図にするとこんなイメージです。
Railsアプリ
↓「このジョブをやっておいて」
Redis(キュー)← ジョブが溜まっていく
↓
Sidekiq(ワーカー)← キューからジョブを取り出して実行
実際のコードを見てみよう
Workerを作る
class WelcomeEmailWorker
include Sidekiq::Worker
def perform(user_id)
user = User.find(user_id)
UserMailer.welcome_email(user).deliver_now
end
end
perform メソッドの中に、実際にやりたい処理を書きます。
ジョブを依頼する
# コントローラーなどから呼び出す
WelcomeEmailWorker.perform_async(user.id)
perform_async を呼ぶだけで、Sidekiqにジョブが登録されます。これだけでバックグラウンド処理の完成です。
時間を指定して実行することもできる
# 10分後に実行
WelcomeEmailWorker.perform_in(10.minutes, user.id)
# 明日の朝9時に実行
WelcomeEmailWorker.perform_at(Time.zone.tomorrow.beginning_of_day + 9.hours, user.id)
Sidekiqを使うメリット
ユーザー体験が良くなる 画面がフリーズしたような待ち時間がなくなります。
サーバーへの負荷を分散できる 重い処理を時間をずらして実行できます。
失敗したときに自動でリトライしてくれる ネットワークエラーなどで失敗しても、Sidekiqが自動で再実行してくれます。
Sidekiqを導入するには
必要なもの
- Redisのインストール
-
sidekiqgem の追加
Gemfileに追加
gem 'sidekiq'
Redisのインストール(Mac)
brew install redis
brew services start redis
Sidekiqの起動
bundle exec sidekiq
Railsサーバーとは別のターミナルで起動します。開発中はRailsサーバーとSidekiqの2つを同時に動かすイメージです。
まとめ
| 項目 | 内容 |
|---|---|
| Sidekiqとは | バックグラウンドでジョブを処理するライブラリ |
| 使う場面 | メール送信・画像処理・重いデータ処理など |
| 必要なもの | Redis + sidekiq gem |
| 基本の流れ | Workerに処理を書いて perform_async で登録するだけ |
Sidekiqを使いこなせるようになると、ユーザーに優しいRailsアプリが作れるようになります。まずは簡単なメール送信処理から試してみるのがおすすめです!