Ruby2.0, Rails4で確認
resqueは非同期処理を簡単に実現してくれるgemです。
とりあえずレスポンスだけ返して実際の処理は後回しにしたい、という場合にresqueが使えます。
resqueの最新バージョンは2.x系ですが、デフォルトでインストールされるのは1.1系なので1.x系での解説をします。
今回はresqueを使ってhello worldを出力するところまでやってみます。
初期設定
- アプリ作成
rails new resque_sample
- Gemfile追加
resqueはredisを使用するためあらかじめredisをインストールして起動しておく必要があります。
gem 'resque'
- bundle install
./bin/bundle install --path=vendor/bundler
- initializer設定
Workerのnamespaceを環境によって分けるように設定しておきます
Resque.redis = 'localhost:6379'
Resque.redis.namespace = "resque:resque_sample:#{Rails.env}" # アプリ毎に異なるnamespaceを定義しておく
Controller作成
- homeコントローラを作成
./bin/rails g controller home
- routing設定
get "hello/:message" => 'home#hello'
- indexアクション編集
class HomeController < ApplicationController
def hello
Resque.enqueue(Hello, params[:message])
render :text => params[:message]
end
end
ResqueWorker作成
- resque worker用のディレクトリを作成
mkdir app/workers
- worker作成
class Hello
@queue = :resque_sample # Woeker起動時に指定するQUEUE名
def self.perform(message)
sleep 5
logger = Logger.new(File.join(Rails.root, 'log', 'resque.log'))
logger.info "Hello #{message}"
end
end
- Rakeタスクを追加
require 'resque/tasks'
- worker起動
QUEUEにworker名を指定します。
QUEUE=resque_sample rake environment resque:work
# すべてのworkerを対象としたい場合は*を指定
QUEUE=* rake environment resque:work
確認
ブラウザから
にアクセスして
tail -f log/resque.log
を眺めていると数秒後にログに
Hello world
Hello resque
が記録されます。
Daemon化してみる
daemon-spawnというgemを用いることでresqueの処理をdaemon化できます。
- Gemfile追加
requireの指定を忘れないように注意
gem 'daemon-spawn', :require => 'daemon_spawn'
- bundle install
./bin/bundle install
- daemon起動スクリプトの作成
#!/usr/bin/env ruby
require File.expand_path('../../config/application', __FILE__)
Rails.application.require_environment!
class ResqueWorkerDaemon < DaemonSpawn::Base
def start(args)
@worker = Resque::Worker.new('resque_sample') # 複数のworkerがある場合はカンマ区切りで指定
@worker.verbose = true
@worker.work
end
def stop
end
end
ResqueWorkerDaemon.spawn!({
:processes => 1, # プロセス数の指定
:working_dir => Rails.root,
:pid_file => File.join(Rails.root, 'tmp', 'pids', 'resque_worker.pid'),
:log_file => File.join(Rails.root, 'log', 'resque_worker.log'),
:sync_log => true,
:singleton => true,
:signal => 'QUIT'
})
複数のworkerがある場合はカンマ区切りで
@worker = Resque::Worker.new('worker1', 'worker2')
と記述します。
workerに追加した順番で優先順位が決まるので上記の例だとworker1の方が優先度が高くなります。
- 実行権限を付与
chmod 755 bin/resque_worker
- daemon起動
RAILS_ENV=development ./bin/resque_worker start
これでworkerをdaemon化することができました。
再度ブラウザからアクセスすれば正しくログに記録されていきます。
- その他のコマンド
停止
RAILS_ENV=development ./bin/resque_worker stop
再起動
RAILS_ENV=development ./bin/resque_worker restart
まとめ
今回はhello worldをログに残す簡単なサンプルでしたが、resqueを使用することで手軽にジョブキューシステムを導入できました。
レスポンスだけ素早く返して重い処理を後回しにしたい、という場合はresqueの検討をしてみてはいかがでしょうか。
参考
- Hello World Resque (Railsにresqueを導入する)
- resque / resque
- Resqueを利用したRailsでの非同期処理/バッチ処理
- Rails3 で resque を使う #1
- RailsでResqueを使ってメルマガ配信の仕組みを作る
- Resqueを利用したRailsアプリを、1台のサーバで複数動かす
- Rails3.2.8 + Resque + Heroku(Redis To Go)
- [Rails][非同期処理]Resqueをはじめる その3 (Resqueを動かす)
- 【Ruby】Railsで重たい処理をバックグラウンドで非同期に処理させるResqueを使ってみた
- iQONのバックエンドの非同期処理について(具体的な実装編)
- Resqueワーカーをデーモンとして動かす
- 実録!Railsのはまりポイント10選
- Setting up Resque