What is Resque
https://github.com/resque/resque
Overview
Resque workers can be distributed between multiple machines, support priorities, are resilient to memory bloat / "leaks," are optimized for REE (but work on MRI and JRuby), tell you what they're doing, and expect failure
Persistent
- Resque queues are persistent
- Support constant time, atomic push and pop (thanks to Redis)
- Provide visibility into their contents
- Store jobs as simple JSON packages.
Tutorial
Sample data
https://github.com/resque/resqueのexmple directoryを見ることをおすすめ
Sample tutorial
resque設定
# config/initializers/resque.rb
Resque.redis = 'localhost:6379'
Resque.redis.namespace = "resque:your_application_name:#{Rails.env}" # アプリ毎に異なるnamespaceを定義しておく
Rakeタスクを追加
# lib/tasks/resque.rake
require 'resque/tasks'
controller作成
jobをtriggerする用途
rails g controller home
router設定
# config/routes.rb
get 'hello/:message' => 'home#hello'
action生成
class HomeController < ApplicationController
def hello
Resque.enqueue(Hello, params[:message])
render :text => params[:message]
end
end
job(worker)作成
# app/jobs/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
確認
curlでtriggerして
curl -v -X GET http://localhost:3000/hello/message_test
ここまでだとredisにjobがたまることは確認できるが、実行はされない
➜ ~ redis-cli
127.0.0.1:6379> keys *
1) "resque:application_name:development:queue:resque_sample"
3) "resque:application_name:development:queues"
LINDEX resque:application_name:development:queue:resque_sample 0
"{\"class\":\"Hello\",\"args\":[\"test2\"]}"
実行させるには workerを起動する必要がある
worker起動
# QUEUEにresque_sampleというworker名を指定します。
QUEUE=resque_sample rake environment resque:work
# すべてのworkerを対象としたい場合は*を指定
QUEUE=* rake environment resque:work
QUEUEは環境変数なのでresqueのrake taskに設定する方法もある
require 'resque/tasks'
namespace :resque do
task setup: :environment do
ENV['QUEUE'] ||= '*'
end
end
ENV['env key']
の指定方法はrailsのenvironment.ymlに値を読み込むこともできる。
http://stackoverflow.com/questions/14457084/getting-ruby-environment-variables-from-rake
fish shellでは環境変数が渡されないのでbassを使って実行
bass QUEUE=resque_sample rake environment resque:work
workerを実行したらjobから登録されているqueueが実行されているlogを確認
tail -f log/resque.log
もう一度redisキーをみるとworker関連のキーが増えたことが確認できる
また逆に溜まっているqueue resque:application_name:development:queue:resque_sample
が処理されなくなっている
127.0.0.1:6379> keys *
1) "resque:application_name:development:workers"
2) "resque:application_name:development:worker:w000000000000m.local:8514:resque_sample:started"
3) "resque:application_name:development:queues"
6) "resque:application_name:development:stat:processed:w000000000000m.local:8514:resque_sample"
7) "resque:application_name:development:workers:heartbeat"
8) "resque:application_name:development:stat:processed"
redisキーの変化
workerを起動してない状態でjobを登録
"resque:application_name:development:queue:resque_sample"
"resque:application_name:development:queues"
workerを起動すると queueが処理されてなくなる。
>> "resque:application_name:development:queue:resque_sample" これはなくなる
"resque:application_name:development:worker:w000000000000m.local:9241:resque_sample"
"resque:application_name:development:workers"
"resque:application_name:development:worker:w000000000000m.local:9241:resque_sample:started"
"resque:application_name:development:queues"
"resque:application_name:development:workers:heartbeat"
queueが処理されるとstat:processedのカウントが変化する
"resque:application_name:development:stat:processed"
実行されるjobsはrails経由ではない(?)ため、 Rubymineなのでbreakpointがひかからない
resque worker
- resque workers are rake task that run forever.
worker起動の時の環境変数について
TERM
resque 環境変数
defaultではapplicationのenvironmentがわからない。 基本的には以下のように実行するが
QUEUE=file_serve rake resque:work
railsでの環境変数を使いたい場合には
QUEUE=file_serve rake environment resque:work
のようにenvironment
をいれて
task "resque:setup" => :environment do
Grit::Git.git_timeout = 10.minutes
end
このように => :enviroment
を入れる
Logging
VVERBOSE(very verbose)
VVERBOSE=1 QUEUE=file_serve rake environment resque:work
failへlogを残したい
# config/initializers/resque.rb
Resque.logger = Logger.new(Rails.root.join('log', "#{Rails.env}_resque.log"))
# jobで以下のように使う
Resque.logger.info('hoge')
Running in the background
PIDFILE=./resque.pid BACKGROUND=yes QUEUE=file_serve rake environment resque:work
Polling frequency
- default 5 seconds
変更したい場合 INTERVALを利用
INTERVAL=0.1 QUEUE=file_serve rake environment resque:work
jobをqueueへ入れるときに注意点
- queueはpersistanceされるし、jsonで扱う。
- なので、queueにはobjectよりは値を渡すのはいい。
- dbの変更や関連gemのversion upにも安全
class Repository
def async_create_archive(branch)
Resque.enqueue(Archive, self.id, branch)
end
end
Daemon化
https://blog.hello-world.jp.net/ruby/895/
resque設定例
# Gemfile
gem 'resque'
# config/application.rb
config.active_job.queue_adapter = :resque
# config/initializers/resque.rb
Resque.redis = 'localhost:6379'
# lib/tasks/resque.rake
require 'resque/tasks'
namespace :resque do
task setup: :environment do
Resque.before_fork = -> _job { ActiveRecord::Base.connection.disconnect! }
Resque.after_fork = -> _job { ActiveRecord::Base.establish_connection }
end
end
Passenger使う?
- https://github.com/resque/resque
- https://www.phusionpassenger.com/documentation/Users%20guide%20Nginx.html#deploying_a_rack_app
References
- https://blog.engineyard.com/2014/getting-started-with-active-job
- http://qiita.com/yimajo/items/c221a9017e4842c33a93
- https://blog.hello-world.jp.net/ruby/895/
- http://qiita.com/iguchi1124/items/e4bf7426ac916acd45e5
- resque home tutorial
- Sample tutorial Resque with ActiveJob