web-dev-qa-db-ja.com

バックグラウンドでresqueを実行する

私は非常にうまく機能するresqueキューシステムを備えた動作中のRailsアプリを持っています。しかし、実際にresqueワーカーをデモンストレーションする良い方法がありません。

Rake resque:work QUEUE = "*"を実行することで、問題なく開始できますが、ワーカーをフォアグラウンドで実行する必要があるということではないと思います。どういうわけか、誰もこの問題に取り組んでいないようです。公式のresquegithubページで、次のようなことができると主張しています。

PIDFILE=./resque.pid BACKGROUND=yes QUEUE="*" rake resque:work

まあ-少なくともここでは背景に分岐しません。

22
Markus

Resque-poolの+ 1-それは本当に素晴らしいです。私たちはそれを神と組み合わせて使用​​し、常に利用できるようにします。

# Resque
God.watch do |w|

  w.dir = Rails_ROOT

  w.name = "resque-pool"
  w.interval = 30.seconds
  w.start = "cd #{Rails_ROOT} && Sudo -u www-data sh -c 'umask 002 && resque-pool -d -E #{Rails_ENV}'"
  w.start_grace = 20.seconds
  w.pid_file = "#{Rails_ROOT}/tmp/pids/resque-pool.pid"

  w.behavior(:clean_pid_file)

  # restart if memory gets too high
  #w.transition(:up, :restart) do |on|
  #  on.condition(:memory_usage) do |c|
  #    c.above = 350.megabytes
  #    c.times = 2
  #  end
  #end

  # determine the state on startup
  w.transition(:init, { true => :up, false => :start }) do |on|
    on.condition(:process_running) do |c|
      c.running = true
    end
  end

  # determine when process has finished starting
  w.transition([:start, :restart], :up) do |on|
    on.condition(:process_running) do |c|
      c.running = true
      c.interval = 5.seconds
    end

    # failsafe
    on.condition(:tries) do |c|
      c.times = 5
      c.transition = :start
      c.interval = 5.seconds
    end
  end

  # start if process is not running
  w.transition(:up, :start) do |on|
    on.condition(:process_running) do |c|
      c.running = false
    end
  end
end

これにより、ジョブを中断することなく、ワーカーにコードをリロードするための非常にエレガントな方法が提供されます-単にkill -2デプロイするときのresque-pool(s)。アイドル状態の労働者はすぐに死に、忙しい労働者は現在の仕事を終えると死に、神はあなたの新しいコードを使用して労働者と一緒にresque-poolを再開します。

CapistranoのResqueタスクは次のとおりです。

namespace :resque do

  desc "Starts resque-pool daemon."
  task :start, :roles => :app, :only => { :jobs => true } do
    run "cd #{current_path};resque_pool -d -e #{Rails_env} start"
  end

  desc "Sends INT to resque-pool daemon to close master, letting workers finish their jobs."
  task :stop, :roles => :app, :only => { :jobs => true } do
    pid = "#{current_path}/tmp/pids/resque-pool.pid"
    Sudo "kill -2 `cat #{pid}`"
  end

  desc "Restart resque workers - actually uses resque.stop and lets God restart in due course."
  task :restart, :roles => :app, :only => { :jobs => true } do
    stop # let God restart.
  end

  desc "List all resque processes."
  task :ps, :roles => :app, :only => { :jobs => true } do
    run 'ps -ef f | grep -E "[r]esque-(pool|[0-9])"'
  end

  desc "List all resque pool processes."
  task :psm, :roles => :app, :only => { :jobs => true } do
    run 'ps -ef f | grep -E "[r]esque-pool"'
  end

end

Resque-pool forksワーカーの場合、DB接続を再接続する必要がある場合があります-ドキュメントを確認してください。

15
Andy Triggs

私は同じ問題を抱えていて、次のことが私のために働いています。

PIDFILE=./resque.pid BACKGROUND=yes QUEUE="*" rake resque:work >>  worker1.log &

STDERRを同じログファイルにリダイレクトすることもできます。

13
mbsheikh

プロセスを悪魔化するには、 Nohup を使用できます:

Nohup cmd &

Resqueの github にmonitの設定があり、Nohupの使用方法を示しています。次のようになります。

Nohup bundle exec rake resque:work QUEUE=queue_name PIDFILE=tmp/pids/resque_worker_QUEUE.pid & >> log/resque_worker_QUEUE.log 2>&1
5
sparrovv

調べる必要があるもう1つのオプションは、 resque pool gemを使用してワーカーを管理することです。

次のコマンドを使用して、バックグラウンドでresquepoolを実行できます。

resque-pool --daemon --environment production

4
Jhony Fung

BACKGROUND環境変数がResque1.20に追加されました。 1.19以下を使用していないことを確認してください。

2
Ian Terrell

私もこの問題に直面しました、私はキャップタスクで労働者を始めます、しかし私は問題を抱えています

  • バックグラウンドにより、ワーカーは常に開始モードになります。
  • Nohupプロセスは終了直後に強制終了されます。数秒待つ必要があります。ただし、「&」の後にコマンドを追加することはできません

最後に、シェルを作成し、Nohup ...呼び出しの5秒後にスリープ状態にする必要があります。私のコード

desc 'Start resque'
task :start, :roles => :app do
  run("cd #{current_path} ; echo \"Nohup bundle exec rake resque:work QUEUE=* Rails_ENV=#{Rails_env} PIDFILE=tmp/pids/resque_worker_1.pid &\nnohup bundle exec rake resque:work QUEUE=* Rails_ENV=#{Rails_env} PIDFILE=tmp/pids/resque_worker_2.pid &\nsleep 5s\" > startworker.sh ")
  run("cd #{current_path} ; chmod +x startworker.sh")
  run("cd #{current_path} ; ./startworker.sh")
  run("cd #{current_path} ; rm startworker.sh")
end

私はこれが状況の解決策であることを知っています。しかし、それは私のプロジェクトではうまく機能します

1
AnVo

良い方法の1つは、 God を使用して管理することです。デーモン化されたバージョンのResqueを起動し、監視します。実際には、Resqueをデーモンとして使用するか、神にResqueをデーモン化させるかを選択できます。オプション2を選択します。

A resque.godファイルの例:

Rails_env   = ENV['Rails_ENV']  || "production"
Rails_root  = ENV['Rails_ROOT'] || "/path/to/my/app/current"
num_workers = Rails_env == 'production' ? 5 : 2

num_workers.times do |num|
  God.watch do |w|
    w.dir      = "#{Rails_root}"
    w.name     = "resque-#{num}"
    w.group    = 'resque'
    w.interval = 30.seconds
    w.env      = {"QUEUE"=>"critical,mailer,high,low", "Rails_ENV"=>Rails_env}
    w.start    = "bundle exec rake -f #{Rails_root}/Rakefile resque:work"
    w.stop_signal = 'QUIT'
    w.stop_timeout = 20.seconds

    w.uid = 'myappuser'
    w.gid = 'myappuser'

    w.behavior(:clean_pid_file)

    # restart if memory gets too high
    w.transition(:up, :restart) do |on|
      on.condition(:memory_usage) do |c|
        c.above = 350.megabytes
        c.times = 2
        c.notify = {:contacts => ['maxime'], :priority => 9, :category => 'myapp'}
      end
    end

    # determine the state on startup
    w.transition(:init, { true => :up, false => :start }) do |on|
      on.condition(:process_running) do |c|
        c.running = true
      end
    end

    # determine when process has finished starting
    w.transition([:start, :restart], :up) do |on|
      on.condition(:process_running) do |c|
        c.running = true
        c.interval = 5.seconds
      end

      # failsafe
      on.condition(:tries) do |c|
        c.times = 5
        c.transition = :start
        c.interval = 5.seconds
      end
    end

    # start if process is not running
    w.transition(:up, :start) do |on|
      on.condition(:process_running) do |c|
        c.running = false
        c.notify = {:contacts => ['maxime'], :priority => 1, :category => 'myapp'}
      end
    end
  end
end
1
Maxime Garcia

this スクリプトを使用してワーカーを管理できます。利用可能なコマンド:

rake resque:start_workers
rake resque:stop_workers
rake resque:restart_workers

resque-scheduler も含まれています。この行にコメントを付けて無効にします。

pid = spawn(env_vars, 'bundle exec rake resque:scheduler', ops_s)
Process.detach(pid)
0
hlcs