Come posso eliminare i lavoratori Resque bloccati / non aggiornati?


132

Come puoi vedere dall'immagine allegata, ho un paio di lavoratori che sembrano bloccati. Tali processi non dovrebbero richiedere più di un paio di secondi.

inserisci qui la descrizione dell'immagine

Non sono sicuro del motivo per cui non verranno cancellati o come rimuoverli manualmente.

Sono su Heroku usando Resque con Redis-to-Go e HireFire per ridimensionare automaticamente i lavoratori.


2
Ciao, domanda semi-correlata: come hai ottenuto la dashboard resque-web tramite heroku? Non riesco a capire come aprirlo.
Aaron segna il

Risposte:


215

Nessuna di queste soluzioni ha funzionato per me, lo vedrei ancora in redis-web:

0 out of 10 Workers Working

Alla fine, questo ha funzionato per me per cancellare tutti i lavoratori:

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

12
Questo ha funzionato per me. Non ha registrato tutti i lavoratori, il che è stato un po 'fastidioso. Ma questo seguito heroku restartsembrava fare il trucco. Ora mostra il numero corretto di lavoratori.
Brian Armstrong,

Ciò ha portato i lavoratori dall'interfaccia web, ma in realtà si presentano ancora come processi e "rubano" i lavori dalla coda
txwikinger

20
Se si desidera annullare la registrazione solo dei lavoratori che non sono processi effettivi (e forse elaborare processi), è possibile provare a Resque.workers.each {|w| matches = w.id.match(/^[^:]*:([0-9]*):[^:]*$/); pid = matches[1]; w.unregister_worker unless w.worker_pids.include?(pid.to_s)}annullare la registrazione solo dei lavoratori i cui pid non fanno parte dei pid in esecuzione noti. Non so se funziona in tutti gli ambienti ma funziona bene su Ubuntu. Questo potrebbe funzionare solo quando i tuoi lavoratori sono sullo stesso computer su cui esegui questo codice.
roychri,

3
Come opzione Resque.workers.map &: unregister_worker
AB

Come mai questo non include un controllo per verificare se il lavoratore non deve essere registrato prima di chiamare unregister_worker? C'è un modo per determinarlo?
user5243421

53

Nella tua console:

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

Altrimenti puoi provare a falsificarli come fatto per rimuoverli, con:

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

MODIFICARE

Molte persone hanno votato a favore di questa risposta e ritengo sia importante che le persone provino la soluzione di hagope che annulla la registrazione dei lavoratori da una coda, mentre il codice sopra elimina le code. Se sei felice di falsificarli, allora fico.


3
Se lo fa eliminerà l'intera coda, vuole solo rimuovere quelli bloccati ..
jBeas,

1
Piccolo aggiornamento: ora devi usare Resque.redis.del invece di Resque.redis.delete
James P McGrath,

1
In realtà c'è un metodo Resque.remove_queue () ora
iainbeeston

28

Probabilmente hai installato la gemma resque, quindi puoi aprire la console e ottenere gli attuali lavoratori

Resque.workers

Restituisce un elenco di lavoratori

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

scegli il lavoratore e prune_dead_workers, ad esempio, il primo

Resque.workers.first.prune_dead_workers

1
In realtà, al secondo tentativo, questo non ha fatto nulla.
Shpigford,

2
Questo funziona alla grande per eliminare i lavoratori che sono stati uccisi senza annullare la registrazione.
Lukas Eklund,

3
Questa sembra la nuova migliore risposta poiché non annulla la registrazione di tutti. Prune_dead_workers non dovrebbe essere un metodo di classe? Ma in ogni caso, un'ottima soluzione! Grazie.
Brian Armstrong,

Questa è sicuramente la soluzione per i lavoratori uccisi -9. L'unica cosa che aggiungerei è che devi farlo sullo stesso server in cui hai ucciso con -9.
Stanislav O. Pogrebnyak,

Fallo a tutti in una volta: Resque.workers.each (&: prune_dead_workers)
Leone,

25

Aggiungendo la risposta di hagope, volevo essere in grado di annullare la registrazione solo dei lavoratori che erano in esecuzione da un certo periodo di tempo. Il codice seguente annulla la registrazione dei lavoratori in esecuzione per oltre 300 secondi (5 minuti).

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

Ho una raccolta in corso di attività Rake correlate a Resque che ho anche aggiunto a: https://gist.github.com/ewherrmann/8809350


3
Punti per mostrare come accedere all'ora di inizio del processo tramite elaborazione ['run_at']. Ho visto altre soluzioni che utilizzano il metodo .started, ma questo in realtà restituisce il momento in cui è stato avviato il lavoratore , non il lavoro, che è l'approccio sbagliato per eliminare i lavoratori bloccati. Grazie!
Lachlan Cotter

10

Esegui questo comando ovunque tu abbia eseguito il comando per avviare il server

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

dovresti vedere qualcosa del genere:

92102 resque: Processing ProcessNumbers since 1253142769

Prendi nota del PID (ID processo) nel mio esempio è 92102

Quindi è possibile uscire dal processo 1 di 2 modi.

  • Usa con grazia QUIT 92102

  • Usa con forza TERM 92102

* Non sono sicuro della sintassi sia QUIT 92102oQUIT -92102

Fammi sapere se hai qualche problema.


3
Nella console Linux: kill -SIGQUIT 92102
Alexey,

6

Ho appena fatto:

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

Ho la lista dei lavoratori.

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

... dove n è l'indice a base zero del lavoratore indesiderato.


2

Ho avuto un problema simile nel fatto che Redis ha salvato il DB su disco che includeva lavoratori non validi (non in esecuzione). Ogni volta che Redis / resque è stato avviato, sono comparsi.

Risolvilo usando:

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

Assicurati di riavviare Redis e i tuoi dipendenti Resque.


2

Ecco come è possibile eliminarli da Redis per nome host. Questo succede a me quando dismesso un server e i lavoratori non escono con garbo.

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

2

Mi sono imbattuto in questo problema e ho iniziato il percorso di attuazione di molti suggerimenti qui. Tuttavia, ho scoperto che la causa principale che stava creando questo problema era che stavo usando la gemma redis-rb 3.3.0 . Il downgrade a redis-rb 3.2.2 ha impedito a questi lavoratori di rimanere bloccati in primo luogo.


1

Iniziato a lavorare su https://github.com/shaiguitar/resque_stuck_queue/ recente. Non è una soluzione su come riparare i lavoratori bloccati, ma affronta il problema della sospensione / dell'essere bloccato, quindi ho pensato che potesse essere utile per le persone su questo thread. Da README:

"Se resque non esegue i lavori entro un determinato periodo di tempo, attiverà un gestore predefinito di tua scelta. Puoi usarlo per inviare un'e-mail, un servizio cercapersone, aggiungere altri lavoratori resque, riavviare resque, inviare un txt. ..qualunque cosa ti si adatti. "

Sono stato usato in produzione e funziona abbastanza bene per me finora.


0

Anche qui avevo lavoratori bloccati / stantii, o dovrei dire "lavori", perché il lavoratore è effettivamente ancora lì e funziona bene, è il processo biforcuto che è bloccato.

Ho scelto la brutale soluzione di uccidere il processo biforcuto "Processing" da più di 5 minuti, tramite uno script bash, quindi il lavoratore ha appena generato il successivo in coda e tutto continua a funzionare

dai un'occhiata alla mia sceneggiatura qui: https://gist.github.com/jobwat/5712437


0

Li ho cancellati direttamente da redis-cli. Fortunatamente redistogo.com consente l'accesso da ambienti esterni a heroku. Ottieni un ID lavoratore morto dall'elenco. Il mio era

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

Esegui questo comando in redis direttamente.

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

Puoi monitorare redis db per vedere cosa sta facendo dietro le quinte.

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 seconda ultima riga elimina il lavoratore.


Non è una buona idea. Questo non chiamerà hook non registrati in Resque, non chiamando il fallimento e il possibile codice di pulizia che le persone potrebbero avere.
Jeremy,

Questo è stato utile con resque 2 anni fa quando mostrava processi bloccati che erano impossibili da eliminare utilizzando l'interfaccia e non c'era un modo pulito per farlo in rotaie
Andrei R

0

Se stai utilizzando le versioni più recenti di Resque, dovrai utilizzare il seguente comando poiché le API interne sono cambiate ...

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

0

Questo evita il problema fintanto che hai una versione resque più recente di 1.26.0:

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

Tenere presente che non consente il completamento del processo in esecuzione.


0

è inoltre possibile utilizzare il comando seguente per interrompere tutto il rescuelavoratore

sudo kill -9  `ps aux | grep resque | grep -v grep | cut -c 10-16`

riferimento da questo link

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.