ruby on rails - ¿Cómo borro los trabajadores de Resque atascados/obsoletos?
ruby-on-rails ruby-on-rails-3 (14)
Al agregar a la respuesta por hagope, quería poder anular el registro solo de los trabajadores que habían estado funcionando durante cierto tiempo. El siguiente código solo cancelará el registro de los trabajadores que se ejecutan durante más de 300 segundos (5 minutos).
Resque.workers.each {|w| w.unregister_worker if w.processing[''run_at''] && Time.now - w.processing[''run_at''].to_time > 300}
Tengo una colección continua de tareas de Rake relacionadas con Resque que también he agregado a: https://gist.github.com/ewherrmann/8809350
Como puede ver en la imagen adjunta, tengo un par de trabajadores que parecen estancados. Esos procesos no deberían tomar más de un par de segundos.
No estoy seguro de por qué no borrarán o cómo eliminarlos manualmente.
Estoy en Heroku usando Resque con Redis-to-Go y HireFire para escalar automáticamente a los trabajadores.
Aquí también trabajé con los trabajadores del resquebrajamiento, o debería decir ''trabajos'', porque el trabajador todavía está allí y funciona bien, es el proceso bifurcado el que está atascado.
Elegí la solución brutal de matar el proceso bifurcado "Procesamiento" desde hace más de 5 minutos, a través de un script bash, luego el trabajador acaba de generar el siguiente en cola, y todo sigue en marcha
echa un vistazo a mi script aquí: https://gist.github.com/jobwat/5712437
Así es como puedes purgarlos de Redis por nombre de host. Esto me sucede cuando desmantelo un servidor y los trabajadores no salen con gracia.
Resque.workers.each { |w| w.unregister_worker if w.id.start_with?(hostname) }
Comencé a trabajar en https://github.com/shaiguitar/resque_stuck_queue/ recientemente. No es una solución a la forma de reparar a los trabajadores trabajados, pero aborda el problema del resque colgado / atorado, así que pensé que podría ser útil para las personas en este hilo. De README:
"Si resque no ejecuta trabajos dentro de un cierto período de tiempo, activará un controlador predefinido de su elección. Puede usarlo para enviar un correo electrónico, servicio de buscapersonas, agregar más trabajadores resque, reiniciar resque, enviarle un txt. ..lo que te venga bien."
Se ha usado en producción y funciona bastante bien para mí hasta ahora.
Ejecute este comando donde quiera que ejecute el comando para iniciar el servidor
$ ps -e -o pid,command | grep [r]esque
Debería ver algo como esto:
92102 resque: Processing ProcessNumbers since 1253142769
Tome nota del PID (identificación del proceso) en mi ejemplo es 92102
Entonces puede salir del proceso 1 de 2 maneras.
Utilice con
QUIT 92102
Utilice
TERM 92102
* No estoy seguro de la sintaxis, ya sea QUIT 92102
o QUIT -92102
Avísame si tienes algún problema.
En tu consola:
queue_name = "process_numbers"
Resque.redis.del "queue:#{queue_name}"
De lo contrario, puede intentar falsificarlos como si se hubieran hecho para eliminarlos, con:
Resque::Worker.working.each {|w| w.done_working}
EDITAR
Mucha gente ha estado votando esta respuesta y creo que es importante que la gente pruebe la solución de hapeca, que anula el registro de los trabajadores de una cola, mientras que el código anterior elimina las colas. Si estás feliz de falsificarlos, entonces genial.
Esto evita el problema siempre que tengas una versión resque más nueva que 1.26.0:
resque: env QUEUE=foo TERM_CHILD=1 bundle exec rake resque:work
Tenga en cuenta que no permite que finalice el trabajo actualmente en ejecución.
Lo acabo de hacer:
% rails c production
irb(main):001:0>Resque.workers
Tengo la lista de trabajadores.
irb(main):002:0>Resque.remove_worker(Resque.workers[n].id)
... donde n es el índice basado en cero del trabajador no deseado.
Los borré de redis-cli directamente. Afortunadamente, redistogo.com permite el acceso desde entornos fuera de heroku. Obtener ID de trabajador muerto de la lista. El mío era
55ba6f3b-9287-4f81-987a-4e8ae7f51210:2
Ejecute este comando en redis directamente.
del "resque:worker:55ba6f3b-9287-4f81-987a-4e8ae7f51210:2:*"
Puede supervisar redis db para ver qué está haciendo detrás de escena.
redis xxx.redistogo.com> MONITOR
OK
1380274567.540613 "MONITOR"
1380274568.345198 "incrby" "resque:stat:processed" "1"
1380274568.346898 "incrby" "resque:stat:processed:c65c8e2b-555a-4a57-aaa6-477b27d6452d:2:*" "1"
1380274568.346920 "del" "resque:worker:c65c8e2b-555a-4a57-aaa6-477b27d6452d:2:*"
1380274568.348803 "smembers" "resque:queues"
La segunda última línea borra al trabajador.
Me encontré con este problema y comencé a implementar muchas de las sugerencias aquí. Sin embargo, descubrí que la causa raíz que creaba este problema era que estaba usando la gema redis-rb 3.3.0 . La degradación a redis-rb 3.2.2 impidió que estos trabajadores se estancaran en primer lugar.
Ninguna de estas soluciones funcionó para mí, todavía vería esto en redis-web:
0 out of 10 Workers Working
Finalmente, esto funcionó para mí para eliminar a todos los trabajadores:
Resque.workers.each {|w| w.unregister_worker}
Probablemente tengas instalada la gema de resque, para que puedas abrir la consola y obtener trabajadores actuales
Resque.workers
Devuelve una lista de trabajadores
#=> [#<Worker infusion.local:40194-0:JAVA_DYNAMIC_QUEUES,index_migrator,converter,extractor>]
elija el trabajador y prune_dead_workers
, por ejemplo, el primero
Resque.workers.first.prune_dead_workers
Si está utilizando versiones más nuevas de Resque, deberá usar el siguiente comando ya que las API internas han cambiado ...
Resque::WorkerRegistry.working.each {|work| Resque::WorkerRegistry.remove(work.id)}
Tuve un problema similar que Redis guardó la base de datos en el disco que incluía trabajadores inválidos (no en ejecución). Cada vez que se iniciaba Redis / resque aparecían.
Arregle esto usando:
Resque::Worker.working.each {|w| w.done_working}
Resque.redis.save # Save the DB to disk without ANY workers
Asegúrese de reiniciar Redis y sus trabajadores de Resque.