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使う?

References

#

results matching ""

    No results matching ""