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
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