Help us understand the problem. What is going on with this article?

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

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away