Resqueを利用したRailsでの非同期処理/バッチ処理
Railsアプリケーションの中で非同期処理(バッチ処理)を実現したいことがあります。例えば、こんな場合です。
- ユーザーが「送信」ボタンを押したら数千通のメールを送る。
数千通のメールを送るにはかなり時間がかかるので、その処理は後回しにして、ユーザーにはすぐにレスポンスを返したいところです。
非同期処理を行うためのRubyライブラリとしてはBackgrounDRbやdelayed_jobなどが有名ですが、もう一つ有望な選択肢としてResqueというのがあることを最近知りました。
と言っても、私が知らなかっただけで、RubyGems.orgによれば11万回以上もダウンロードされている有名なライブラリです。昨年(2010年)1月に書かれた、あるブログ記事には詳しい評価が載っています。
以下、私の試用報告を書きます。なお、OSはUbuntu 10.04(LTS)、Railsのバージョンは3.0.5です。
ResqueはバックエンドとしてRedisを用います。最近話題のNoSQLデータベースの一種です。まず、これをインストールします。
$ sudo apt-get install redis-server
インストールに成功したら、念のためバージョン番号を確認します。
$ redis-cli --version redis-cli 2.2.2
続いて、動作確認のためのRailsアプリケーションを作ります。名前は適当に、kodamaとしておきましょうか。
$ rails new kodama $ cd kodama
Gemfileに必要なgemライブラリを列挙します。
source 'http://rubygems.org' gem 'rails', '3.0.5' gem 'sqlite3' gem 'resque' gem 'SystemTimer', :platform => :ruby_18
[訂正] SystemTimer は Ruby 1.9 では不要です。
gemライブラリをインストールします。
$ bundle install
config/initializersディレクトリにload_resque.rbというファイルを作ります。
require 'resque' Resque.redis = 'localhost:6379'
config/routes.rbを次のように変更します。
Kodama::Application.routes.draw do get 'hello/:text', :to => 'hello#show' end
app/controllersディレクトリにhello_controller.rbというファイルを作ります。
class HelloController < ApplicationController
def show
Resque.enqueue(Echo, params[:text])
render :text => params[:text]
end
end
appディレクトリの下にworkersディレクトリを作り、そこにecho.rbというファイルを作ります。
class Echo
@queue = :default
def self.perform(text)
sleep 3
path = File.expand_path("log/echo.log", Rails.root)
File.open(path, 'a') do |f|
f.puts "Hello #{text}!"
end
end
end
lib/tasksディレクトリにresque.rakeというファイルを作ります。
require 'resque/tasks'
空のログファイルを作ります。
$ touch log/echo.log
これで準備完了です。
ワーカーを起動します。
$ QUEUE=default rake environment resque:work
別のターミナルを開いて、Railsサーバを起動します。
$ rails server
さらに別のターミナルを開いて、ログファイルを監視してください。
$ tail -f log/echo.log
ここで、ブラウザで http://localhost:3000/hello/world にアクセスします。ログファイルに注目してください。アクセスした瞬間、ブラウザには「world」と表示されますが、ログファイルには何も起こりません。しかし、約3秒数秒後に
Hello world!
と表示されます。さらに、http://localhost:3000/hello/boys にアクセスすると、やはり約3秒数秒おいてログファイルに
Hello boys!
という行が追加されます。
うーむ。驚くほど簡単ですね!
[訂正] 本文中で2回「約3秒」と書きましたが、「数秒」と訂正します。実は、ワーカーは5秒間隔で新たなタスクが追加されていないかチェックしているので、アクセスのタイミングによって3秒後から8秒後にログファイルが書き換わります。(2011/03/23朝)
もう夜も遅いのでソースコードの説明はしませんが、何となく使い方はお分かりになるんじゃないでしょうか。
ポイントを挙げるとすれば、Echoクラスのクラスインスタンス変数@queueにセットした:defaultというシンボルです。これは何でもいいのですが、ここで指定した値が、ワーカーを起動するときの環境変数QUEUEの値になります。両者を一致させる点に注意してください。
なお、ファイル echo.rb を置くディレクトリは、app/modelsでもいいです。
書いてある通りにやってみたけど動かないよ、という方は、ワーカーを起動するコマンドを次のように変更してみてください。
$ QUEUE=default VVERBOSE=true rake environment resque:work
状況が細かく画面に表示されますので、うまく動かない原因が分かるかもしれません。
(2011/03/23)
記事に関するご質問は、 hermes@oiax.jp までメールでお送りください。
ウェブサイト構築の発注先を検討されているお客様は、ご相談フォームをご利用ください。
- はじめに
- Rails はエンタープライズの世界で主流になるか (2008/03/29)
- Rails 2.0 ベンチマーク (2008/03/30)
- テスト駆動開発とデバッグコード (2008/04/07)
- Git or Mercurial (2008/04/22)
- RESTful Ruby on Rails -- その美しさと難しさ (2008/04/23)
- RESTful Ruby on Rails -- 単数と複数 (2008/04/24)
- Rails のソースコードを読む (2008/05/02)
- sudo: no passwd entry for app! (Capistrano 2.3.0) (2008/05/12)
- Rails on GlassFish (2008/06/18)
- 「Ruby は型宣言がないけど、ちゃんとしたシステムに使えるのか」という質問にどう答えるか (2008/11/23)
- 「Ruby はスクリプト言語だけど、遅くないですか」という質問にどう答えるか (2008/11/24)
- どのプログラミング言語が将来的に有望か (2009/01/10)
- どのフレームワークが将来的に有望か (2009/01/11)
- フレームワーク対 CMS (2009/01/12)
- Rails 2.3 で spawner/reaper は DEPRECATED に (2009/03/25)
- db/seeds.rb (2009/06/08)
- LESSとSass (2009/08/03)
- Rails 2.3.4 と I18n (2009/08/15)
- RubyGems のアップデート(上書きインストール) (2010/02/03)
- クリエイティブ・コモンズの Rails 教材 (2010/03/08)
- Yet Another Ruby Reference (2010/03/12)
- Rails で MongoDB を使ってみた (2010/03/23)
- Rails で MongoDB を使ってみた(2) (2010/03/25)
- 祝 Ruby on Rails 3.0 beta2 リリース (2010/04/02)
- Rails 3.x 時代のテストフレームワーク (2010/04/24)
- 続・Rails 3.x 時代のテストフレームワーク (2010/05/06)
- Test::Unit と RSpec と Shoulda (2010/05/06)
- Windows + Rails + MySQL 5.1 (2010/07/20)
- Ruby on Rails 2.3.9 リリース (2010/09/05)
- Railtie と Engine と Plugin の関係 (2010/10/23)
- Rails 3.0 と Internet Explorer (2010/11/19)
- acts_as_list: gem か plugin か (2010/11/29)
- さようならNetBeans/こんにちはRedcar (2011/01/28)
- RubyGems 1.5 が出たけど (2011/02/04)
- はじめる!Rails3 第2巻の執筆を始めました (2011/03/20)
- NetBeans 7.0にRuby on Railsプラグインをインストールする手順 (2011/03/21)
- Resqueを利用したRailsでの非同期処理/バッチ処理 (2011/03/23)
- Resqueワーカーをデーモンとして動かす (2011/04/02)
- はじめる!Rails3 第2巻の執筆(経過報告) (2011/04/23)
- はじめる!Rails3 第2巻の執筆(経過報告 No.2) (2011/05/11)
- Rails 3.1: assign_attributesメソッド (2011/05/14)
- Rails 3.1: has_secure_passwordメソッド (2011/05/27)
- はじめる!Rails3 第2巻の執筆(経過報告 No.3) (2011/06/06)
- Ruby on Rails 3.2 を Windows にインストールする手順をかなり丁寧に説明してみました (2011/07/22)
- Ruby on Rails 3.2 を Mac OS X にインストールする手順をかなり丁寧に説明してみました (2011/08/07)
- はじめる!Rails3 第2巻の執筆(経過報告 No.4) (2011/08/15)
- WindowsマシンにUbuntuをインストールしてRails開発を始めるには (2011/08/29)
- Rails 3.xでISO-2022-JP(JISコード)の電子メールを送る: mail-iso-2022-jp (2011/12/05)
- はじめる!Rails3 第3巻について (2011/12/30)
- NetBeans 7.1にRuby on Railsプラグインをインストールする手順 (2012/01/26)
- はじめる!Rails3 第3巻について(経過報告) (2012/02/29)
- はじめる!Rails3 第3巻について(経過報告2) (2012/03/17)
- Ruby on Railsで複合キーを扱う(1) (2012/03/25)
- Ruby on Railsで複合キーを扱う(2) (2012/03/26)
- Ruby on Railsで複合キーを扱う(3) (2012/03/27)
- Ruby on Railsで複合キーを扱う(4) (2012/03/28)
- Ruby on Railsで複合キーを扱う(5) (2012/03/29)
- Ruby on Railsで複合キーを扱う(6) -- 最終回 (2012/03/31)
- Ruby on Railsで複合キーを扱う(7) -- 補遺 (2012/04/01)
- Ruby on Rails 3.2 を Ubuntu にインストールする手順をかなり丁寧に説明してみました (2012/04/22)
- Ruby on Rails 3.2 を Cygwin にインストールする手順をかなり丁寧に説明してみました (2012/05/05)
- Ruby/Railsを学習・開発する環境としてのCygwin (2012/05/06)
- UbuntuにNetBeans IDE 7.1をインストールする手順 (2012/06/08)
- UbuntuにNetBeans IDE 7.2をインストールする手順 (2012/08/22)
- NetBeans 7.2にRuby on Railsプラグインをインストールする手順 (2012/08/31)
- RSpecとCapybaraでJavaScript/Ajaxをテストする (2012/10/01)
- Passenger 向けに AppArmor を設定する (2013/01/06)
- Railsセキュリティアップデートへの対処法 (2013/01/30)
- NetBeans 7.3にRuby on Railsプラグインをインストールする手順 (2013/05/02)

