ruby-on-rails ruby-on-rails-3 background daemon resque

ruby on rails - Ejecutar resque en segundo plano



ruby-on-rails ruby-on-rails-3 (8)

Tengo una aplicación de rieles que funciona con un sistema de cola de resque que funciona muy bien. Sin embargo, carezco de una buena manera de demonizar realmente a los trabajadores de resque.

Puedo comenzar bien con ellos yendo a rake resque: work QUEUE = "*", pero creo que no es el punto que debes tener a tus trabajadores corriendo en primer plano. Por alguna razón nadie parece abordar este problema. En la página de resque github oficial del reclamo puedes hacer algo como esto:

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

Bueno, al menos aquí no se bifurca en el fondo.


A +1 para resque-pool - realmente oscila. Lo usamos en combinación con Dios para asegurarnos de que siempre esté disponible.

# 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

Esto le brinda una manera realmente elegante de volver a cargar el código en sus trabajadores sin interrumpir los trabajos: simplemente elimine kill -2 su (s) grupo (s) de resque cuando lo implemente. Los trabajadores inactivos morirán de inmediato, los trabajadores ocupados morirán cuando terminen sus trabajos actuales, y Dios reiniciará el proceso de reintegro con los trabajadores usando su nuevo código.

Estas son nuestras tareas de Resque para Capistrano:

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

Es posible que deba volver a conectar las conexiones de la base de datos cuando vuelva a agrupar a los trabajadores de las bifurcaciones: consulte los documentos.


La variable de entorno BACKGROUND se agregó a Resque 1.20; Asegúrate de que no estés usando 1.19 o más bajo.


Otra opción que debe considerar es usar la gema de la agrupación de resque para administrar a sus trabajadores.

Puede ejecutar el conjunto de resque en segundo plano usando este comando:

resque-pool - daemon - producción de ambiente


Para demonizar un proceso puedes usar nohup :

nohup cmd &

En el github de github hay una configuración para monit, que muestra cómo usar nohup, se parece a esto:

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


Puedes gestionar a tus trabajadores con this script. Comandos disponibles:

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

También se incluye resque-scheduler . Comenta estas líneas para desactivarlo:

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


También me enfrenté a este problema, comencé a trabajar en Cap Cap, pero tuve un problema

  • ANTECEDENTES hace que el trabajador siempre esté en modo inicial.
  • El proceso de nohup se cancela justo después de terminar, debemos esperar un par de segundos. Pero no se puede agregar más comandos después de ''&''

Por fin, debo crear una concha, dejar que se duerma 5s después de que nohup ... llame. Mi código

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

Sé que esta es una solución de situación. pero funciona bien en mi proyecto


Tuve el mismo problema y los siguientes trabajos para mí.

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

También puede redirigir STDERR al mismo archivo de registro.


Una buena manera es usar a God para manejarlo. Lanza una versión daemonizada de Resque y la monitorea. En realidad, puede elegir entre usar Resque como demonio y dejar que Dios déemonice Resque. Elijo la opción 2.

Un ejemplo de archivo 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