Hello World Resque (Railsにresqueを導入する)
Ruby2.0, Rails4で確認
resqueは非同期処理を簡単に実現してくれるgemです。
とりあえずレスポンスだけ返して実際の処理は後回しにしたい、という場合にresqueが使えます。
resqueの最新バージョンは2.x系ですが、デフォルトでインストールされるのは1.1系なので1.x系での解説をします。
今回はresqueを使ってhello worldを出力するところまでやってみます。
resque workerのdaemon化もやってみます。
redisのインストール(mac)
resqueはredisを使用するためあらかじめredisをインストールして起動しておく必要があります。
- brewでインストール
brew install redis
- redis起動
redis-server
初期設定
- アプリ作成
rails new resque_sample
- Gemfile追加
# Gemfile
gem 'resque'
- bundle install
./bin/bundle install --path=vendor/bundler
- initializer設定
Workerのnamespaceを環境によって分けるように設定しておきます
# config/initializers/resque.rb
Resque.redis = 'localhost:6379'
Resque.redis.namespace = "resque:resque_sample:#{Rails.env}" # アプリ毎に異なるnamespaceを定義しておく
Controller作成
- homeコントローラを作成
./bin/rails g controller home
- routing設定
# config/routes.rb
get "hello/:message" => 'home#hello'
- indexアクション編集
# app/controllers/home_controller.rb
class HomeController < ApplicationController
def hello
Resque.enqueue(Hello, params[:message])
render :text => params[:message]
end
end
ResqueWorker作成
- resque worker用のディレクトリを作成
mkdir app/workers
- worker作成
# app/workers/hello.rb
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タスクを追加
# lib/tasks/resque.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の指定を忘れないように注意
# Gemfile
gem 'daemon-spawn', :require => 'daemon_spawn'
- bundle install
./bin/bundle install
- daemon起動スクリプトの作成
# bin/resque_worker
#!/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の検討をしてみてはいかがでしょうか。
今回のサンプルコードはこちらに置いておきます: hilotter / resque_sample
参考
- resque / resque
- Resqueを利用したRailsでの非同期処理/バッチ処理
- Rails3 で resque を使う #1
- RailsでResqueを使ってメルマガ配信の仕組みを作る
- Resqueを利用したRailsアプリを、1台のサーバで複数動かす
- Rails3.2.8 + Resque + Heroku(Redis To Go)
- [[Rails][非同期処理]Resqueをはじめる その3 (Resqueを動かす)](http://namakesugi.blog42.fc2.com/blog-entry-117.html)
- 【Ruby】Railsで重たい処理をバックグラウンドで非同期に処理させるResqueを使ってみた
- iQONのバックエンドの非同期処理について(具体的な実装編)
- Resqueワーカーをデーモンとして動かす
- 実録!Railsのはまりポイント10選
- Setting up Resque