Comment effacer les travailleurs Resque bloqués / périmés?


132

Comme vous pouvez le voir sur l'image ci-jointe, j'ai quelques ouvriers qui semblent bloqués. Ces processus ne devraient pas prendre plus de quelques secondes.

entrez la description de l'image ici

Je ne sais pas pourquoi ils ne s'effaceront pas ou comment les supprimer manuellement.

Je suis sur Heroku en utilisant Resque avec Redis-to-Go et HireFire pour mettre à l'échelle automatiquement les travailleurs.


2
Salut, question semi-liée: comment avez-vous obtenu le tableau de bord resque-web via heroku? Je n'arrive pas à comprendre comment l'ouvrir.
Aaron marque

Réponses:


215

Aucune de ces solutions n'a fonctionné pour moi, je verrais toujours ceci dans redis-web:

0 out of 10 Workers Working

Enfin, cela a fonctionné pour moi pour effacer tous les travailleurs:

Resque.workers.each {|w| w.unregister_worker}

12
Cela a fonctionné pour moi. Il a désenregistré tous les travailleurs, ce qui était un peu ennuyeux. Mais cela suivi de heroku restartsemblait faire l'affaire. Il montre maintenant le nombre correct de travailleurs.
Brian Armstrong

Cela a retiré les travailleurs de l'interface Web, mais en fait, ils apparaissent toujours comme des processus et ont également «volé» des tâches de la file d'attente
txwikinger

20
Si vous souhaitez désenregistrer uniquement les Resque.workers.each {|w| matches = w.id.match(/^[^:]*:([0-9]*):[^:]*$/); pid = matches[1]; w.unregister_worker unless w.worker_pids.include?(pid.to_s)}nœuds de calcul qui ne sont pas des processus réels (et peut-être des travaux de traitement), vous pouvez essayer de supprimer uniquement les nœuds de calcul dont les pids ne font pas partie des pids en cours d'exécution connus. Je ne sais pas si cela fonctionne dans tous les environnements mais cela fonctionne bien sur ubuntu. Cela peut ne fonctionner que lorsque vos travailleurs sont sur la même machine sur laquelle vous exécutez ce code.
roychri

3
En option Resque.workers.map &: unregister_worker
AB

Comment se fait-il que cela n'inclut pas une vérification pour savoir si le travailleur doit être désinscrit avant d'appeler unregister_worker? Y a-t-il un moyen de déterminer cela?
user5243421

53

Dans votre console:

queue_name = "process_numbers"
Resque.redis.del "queue:#{queue_name}"

Sinon, vous pouvez essayer de les simuler comme étant fait pour les supprimer, avec:

Resque::Worker.working.each {|w| w.done_working}

ÉDITER

Beaucoup de gens ont voté pour cette réponse et je pense qu'il est important que les gens essaient la solution de hagope qui désenregistre les travailleurs d'une file d'attente, alors que le code ci-dessus supprime les files d'attente. Si vous êtes heureux de les simuler, alors cool.


3
S'il fait cela, il supprimera toute la file d'attente, il veut simplement supprimer ceux qui sont bloqués ..
jBeas

1
Petite mise à jour: Vous devez maintenant utiliser Resque.redis.del au lieu de Resque.redis.delete
James P McGrath

1
Il existe en fait une méthode Resque.remove_queue () maintenant
iainbeeston

28

Vous avez probablement installé le gem resque, vous pouvez donc ouvrir la console et obtenir les travailleurs actuels

Resque.workers

Il renvoie une liste de travailleurs

#=> [#<Worker infusion.local:40194-0:JAVA_DYNAMIC_QUEUES,index_migrator,converter,extractor>]

choisissez le travailleur et prune_dead_workers, par exemple, le premier

Resque.workers.first.prune_dead_workers

1
En fait, au deuxième essai, cela n'a rien fait.
Shpigford

2
Cela fonctionne très bien pour éliminer les travailleurs de resque qui ont été tués sans se désinscrire.
Lukas Eklund

3
Cela semble être la nouvelle meilleure réponse car elle ne les annule pas toutes. Prune_dead_workers ne devrait-il pas être une méthode de classe? Mais en tout cas, excellente solution! Merci.
Brian Armstrong

C'est définitivement la solution pour les travailleurs tués -9. La seule chose que j'ajouterais est que vous devez le faire sur le même serveur où vous avez tué avec -9.
Stanislav O. Pogrebnyak

Faites-le à tous à la fois: Resque.workers.each (&: prune_dead_workers)
Leo

25

Ajoutant à répondre par hagope, je voulais pouvoir désinscrire uniquement les travailleurs qui avaient fonctionné pendant un certain temps. Le code ci-dessous annulera uniquement les travailleurs exécutés pendant plus de 300 secondes (5 minutes).

Resque.workers.each {|w| w.unregister_worker if w.processing['run_at'] && Time.now - w.processing['run_at'].to_time > 300}

J'ai une collection en cours de tâches de rake liées à Resque auxquelles j'ai également ajouté ceci: https://gist.github.com/ewherrmann/8809350


3
Points pour montrer comment accéder à l'heure de début du travail via le traitement ['run_at']. J'ai vu d'autres solutions qui utilisent la méthode .started, mais cela renvoie en fait l'heure à laquelle le travailleur a été démarré, pas le travail, ce qui est la mauvaise approche pour éliminer les travailleurs bloqués. Merci!
Lachlan Cotter

10

Exécutez cette commande partout où vous avez exécuté la commande pour démarrer le serveur

$ ps -e -o pid,command | grep [r]esque

vous devriez voir quelque chose comme ceci:

92102 resque: Processing ProcessNumbers since 1253142769

Notez le PID (identifiant de processus) dans mon exemple, il s'agit de 92102

Ensuite, vous pouvez quitter le processus de 1 à 2 façons.

  • Utilisez gracieusement QUIT 92102

  • Utiliser avec force TERM 92102

* Je ne suis pas sûr de la syntaxe c'est soit QUIT 92102ouQUIT -92102

Faites-moi savoir si vous rencontrez des problèmes.


3
Dans la console Linux: kill -SIGQUIT 92102
Alexey

6

Je viens de faire:

% rails c production
irb(main):001:0>Resque.workers

J'ai la liste des travailleurs.

irb(main):002:0>Resque.remove_worker(Resque.workers[n].id)

... où n est l'index de base zéro du travailleur indésirable.


2

J'ai eu un problème similaire lorsque Redis a enregistré la base de données sur un disque contenant des travailleurs invalides (non en cours d'exécution). Chaque fois que Redis / resque a été lancé, ils sont apparus.

Corrigez cela en utilisant:

Resque::Worker.working.each {|w| w.done_working}
Resque.redis.save # Save the DB to disk without ANY workers

Assurez-vous de redémarrer Redis et vos nœuds de calcul Resque.


2

Voici comment vous pouvez les purger de Redis par nom d'hôte. Cela m'arrive lorsque je désactive un serveur et que les travailleurs ne quittent pas correctement.

Resque.workers.each { |w| w.unregister_worker if w.id.start_with?(hostname) }

2

J'ai rencontré ce problème et j'ai commencé à mettre en œuvre un grand nombre de suggestions ici. Cependant, j'ai découvert que la cause première de ce problème était que j'utilisais le gem redis-rb 3.3.0 . La rétrogradation vers redis-rb 3.2.2 a empêché ces travailleurs de rester bloqués en premier lieu.


1

J'ai commencé à travailler sur https://github.com/shaiguitar/resque_stuck_queue/ récemment. Ce n'est pas une solution pour réparer les travailleurs bloqués, mais cela résout le problème du resque suspendu / bloqué, donc j'ai pensé que cela pourrait être utile pour les personnes sur ce fil. De README:

"Si resque n'exécute pas les travaux dans un certain laps de temps, il déclenchera un gestionnaire prédéfini de votre choix. Vous pouvez l'utiliser pour envoyer un e-mail, faire un téléavertisseur, ajouter plus de travailleurs de resque, redémarrer resque, vous envoyer un txt. .. tout ce qui vous convient. "

A été utilisé en production et fonctionne plutôt bien pour moi jusqu'à présent.


0

J'avais des travailleurs de resque bloqués / périmés ici aussi, ou devrais-je dire `` emplois '', car le travailleur est toujours là et fonctionne bien, c'est le processus fourchu qui est bloqué.

J'ai choisi la solution brutale de tuer le processus fourchu "Processing" depuis plus de 5min, via un script bash, puis le worker vient de générer le suivant dans la file d'attente, et tout continue

jetez un œil à mon script ici: https://gist.github.com/jobwat/5712437


0

Je les ai effacés directement de redis-cli. Heureusement, redistogo.com permet l'accès à partir d'environnements extérieurs à heroku. Obtenez l'ID de travailleur mort dans la liste. Le mien était

55ba6f3b-9287-4f81-987a-4e8ae7f51210:2

Exécutez cette commande directement dans Redis.

del "resque:worker:55ba6f3b-9287-4f81-987a-4e8ae7f51210:2:*"

Vous pouvez surveiller redis db pour voir ce qu'il fait dans les coulisses.

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 deuxième dernière ligne supprime le travailleur.


Pas une bonne idée. Cela n'appellera pas les hooks de désinscription dans Resque, pas d'échec d'appel et de code de nettoyage possible que les gens peuvent avoir.
Jeremy

Cela a été utile avec resque il y a 2 ans lorsqu'il montrait des travaux bloqués qui étaient impossibles à supprimer à l'aide de l'interface et qu'il n'y avait pas de moyen propre de le faire dans les rails
Andrei R

0

Si vous utilisez des versions plus récentes de Resque, vous devrez utiliser la commande suivante car les API internes ont changé ...

Resque::WorkerRegistry.working.each {|work| Resque::WorkerRegistry.remove(work.id)}

0

Cela évite le problème tant que vous avez une version de resque plus récente que 1.26.0:

resque: env QUEUE=foo TERM_CHILD=1 bundle exec rake resque:work

Gardez à l'esprit qu'il ne laisse pas la tâche en cours d'exécution se terminer.


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.