Ruby
Rails
Resque

Hello World Resque (Railsにresqueを導入する)

More than 5 years have passed since last update.

Ruby2.0, Rails4で確認

resqueは非同期処理を簡単に実現してくれるgemです。

とりあえずレスポンスだけ返して実際の処理は後回しにしたい、という場合にresqueが使えます。

resqueの最新バージョンは2.x系ですが、デフォルトでインストールされるのは1.1系なので1.x系での解説をします。

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を環境によって分けるように設定しておきます


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の指定を忘れないように注意

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の検討をしてみてはいかがでしょうか。


参考