Resqueワーカーをデーモンとして動かす
2011/04/02
先日の記事(Resqueを利用したRailsでの非同期処理/バッチ処理)の続きです。
簡単に振り返っておきましょう。今、localhost:3000
でRailsアプリが動いています。ユーザーが/hello/world
にアクセスすると、すぐにレスポンスが返ってきます。しかし、数秒経過すると専用のログにテキストが書き込まれます。こういう仕組みを作りました。
この仕組みの鍵になるのが、Resqueというライブラリです。Railsアプリ側でクラスメソッドResque.enqueue
を呼ぶと、非同期で実行したい処理(ジョブ)を登録できます。他方、Railsアプリとは別のプロセスでResqueワーカーというものが動いていて、数秒ごとに新しいジョブが登録されていないか監視しています。新しいジョブを見つけると、それを実行して、また監視作業に戻ります。
さて、前回はターミナルで resque:work
というRakeタスクを実行することによりResqueワーカーを起動しました。開発中はこれでいいのですが、実環境ではデーモンとして実行させたいところです。デーモン(Daemon)とはバックグラウンドで動作するプログラムのことです。デーモンにすれば、起動コマンドを実行したターミナルを閉じても動き続けてくれます。CapistranoでResqueワーカーの起動・停止・再起動をしたい場合、デーモン化は必須です。
Rubyプログラムをデーモン化するのに利用できそうなライブラリとしては、daemons, daemon_controllerなどがありますが、私はdaemon-spawnを試してみることにしました。
まず、Gemfileにdaemon-spawnを追加します。
source 'http://rubygems.org' gem 'rails', '3.0.5' gem 'sqlite3' gem 'resque' gem 'SystemTimer', :platform => :ruby_18 gem 'daemon-spawn', :require => 'daemon_spawn'
インストールします。
$ bundle install
新規ファイル script/echo_server
を作ります。
#!/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('default') @worker.verbose = true @worker.work end def stop @worker.try(:shutdown) end end ResqueWorkerDaemon.spawn!({ :working_dir => Rails.root, :pid_file => File.join(Rails.root, 'tmp', 'pids', 'echo_server.pid'), :log_file => File.join(Rails.root, 'log', 'echo_server.log'), :sync_log => true, :singleton => true })
実行権限を与えます。
$ chmod u+x script/echo_server
これで準備完了です。
デーモンを起動してみましょう。
$ script/echo_server start
プロセスIDを調べて…
$ cat tmp/pids/echo_server.pid 8508
psコマンドを実行すると…
$ ps up 8508 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND kuroda 8508 0.0 0.6 144088 26144 ? Sl 01:45 0:00 resque-1.15
TTYの列が「?」になっているので、確かにデーモン化されています。
デーモンを停止するのは簡単です。
$ script/echo_server stop
もちろん再起動のコマンドもあります。
$ script/echo_server restart