Sıkışmış / eskimiş İşçileri nasıl temizlerim?


132

Ekteki resimden de görebileceğiniz gibi, sıkışmış görünen birkaç işçim var. Bu işlemler birkaç saniyeden uzun sürmemelidir.

görüntü açıklamasını buraya girin

Neden temizlenmeyeceklerinden veya manuel olarak nasıl kaldırılacağından emin değilim.

Çalışanları otomatik olarak ölçeklendirmek için Redis-to-Go ve HireFire ile Resque kullanarak Heroku'dayım.


2
Merhaba, yarı ilgili soru: Heroku aracılığıyla resque-web kontrol panelini nasıl edindiniz? Nasıl açacağımı çözemiyorum.
Aaron Marks

Yanıtlar:


215

Bu çözümlerin hiçbiri benim için işe yaramadı, bunu yine de redis-web'de görüyordum:

0 out of 10 Workers Working

Sonunda, bu tüm işçileri temizlemem için çalıştı:

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

12
Bu benim için çalıştı. Biraz can sıkıcı olan tüm işçilerin kayıtlarını sildi. Ancak bunu takiben heroku restart, hile yapıyor gibiydi. Şimdi doğru işçi sayısını gösteriyor.
Brian Armstrong

Bu, çalışanları web arayüzünden çıkardı, ancak aslında süreçler olarak görünüyorlar ve aynı zamanda işleri kuyruktan "çaldılar"
txwikinger

20
Yalnızca gerçek süreçler olmayan (ve belki de işleri işleyen) Resque.workers.each {|w| matches = w.id.match(/^[^:]*:([0-9]*):[^:]*$/); pid = matches[1]; w.unregister_worker unless w.worker_pids.include?(pid.to_s)}çalışanların kaydını silmek istiyorsanız, hangisinin yalnızca pids'in bilinen çalışan pid'lerin parçası olmadığı çalışanların kaydını sileceğini denemek isteyebilirsiniz . Bunun her ortamda işe yarayıp yaramadığını bilmiyorum ama ubuntu üzerinde iyi çalışıyor. Bu, yalnızca çalışanlarınız bu kodu çalıştırdığınız makinede olduğunda işe yarayabilir.
roychri

3
Bir seçenek olarak Resque.workers.map &: unregister_worker
AB

Bu nasıl işçi olsun bir çek içermez gelip gerektiğini çağırmadan önce ruhsatlı olmayan edilecek unregister_worker? Bunu belirlemenin bir yolu var mı?
user5243421

53

Konsolunuzda:

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

Aksi takdirde, bunları kaldırmak için yapılıyormuş gibi göstermeyi deneyebilirsiniz, bununla:

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

DÜZENLE

Pek çok insan bu cevaba olumlu oy veriyor ve insanların kuyrukları silerken yukarıdaki kod kuyrukları silerken, çalışanların işçileri kuyruktan silen hagope çözümünü denemelerinin önemli olduğunu düşünüyorum. Onları taklit etmekten mutluysan, o zaman havalı.


3
Bunu yaparsa, tüm kuyruğu silecek, sadece sıkışmış olanları kaldırmak istiyor ..
jBeas

1
Küçük güncelleme: Artık Resque.redis.delete yerine Resque.redis.del'i kullanmanız gerekiyor
James P McGrath

1
Aslında şu anda bir Resque.remove_queue () yöntemi var
iainbeeston

28

Muhtemelen resque gem yüklediniz, böylece konsolu açabilir ve mevcut çalışanları elde edebilirsiniz.

Resque.workers

Çalışanların bir listesini verir

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

işçiyi ve prune_dead_workersörneğin ilkini seçin

Resque.workers.first.prune_dead_workers

1
Aslında ikinci denemede bu hiçbir şey yapmadı.
Shpigford

2
Bu, kayıtsız olarak öldürülen direniş işçilerini temizlemek için harika çalışıyor.
Lukas Eklund

3
Hepsinin kaydını silmediği için bu yeni en iyi cevap gibi görünüyor. Prune_dead_workers bir sınıf yöntemi olmamalı mı? Ama her halükarda harika bir çözüm! Teşekkürler.
Brian Armstrong

Ölen -9 işçi için kesinlikle çözüm bu. Ekleyeceğim tek şey, bunu -9 ile öldürdüğünüz sunucuda yapmanız gerektiğidir.
Stanislav O.Pogrebnyak

Hepsine aynı anda yapın: Resque.workers.each (&: prune_dead_workers)
Aslan

25

Hagope yanıtına ek olarak, yalnızca belirli bir süredir çalışan işçilerin kaydını silebilmek istedim. Aşağıdaki kod yalnızca 300 saniyeden fazla (5 dakika) çalışan işçilerin kaydını silecektir.

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

Bunu da şu adrese eklediğim, Devam eden bir Yeniden Ayarlama ile ilgili Rake görevleri koleksiyonum var: https://gist.github.com/ewherrmann/8809350


3
['Run_at'] işlenerek iş başlangıç ​​zamanına nasıl erişileceğini gösteren noktalar. Ben .started yöntemi kullanan diğer çözümler gördüm ama bu aslında zaman döndüren işçi sıkışmış işçileri temizlemek için yanlış yaklaşım değil iş, başlandı. Teşekkürler!
Lachlan Cotter

10

Sunucuyu başlatmak için komutu çalıştırdığınız her yerde bu komutu çalıştırın.

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

bunun gibi bir şey görmelisin:

92102 resque: Processing ProcessNumbers since 1253142769

Örneğimdeki PID'yi (işlem kimliği) not edin, 92102

O zaman işlemden 1/2 yoldan çıkabilirsiniz.

  • Nazikçe kullanın QUIT 92102

  • Zorla kullan TERM 92102

* Sözdiziminden emin değilim, o daQUIT 92102 daQUIT -92102

Herhangi bir sorununuz olursa bana bildirin.


3
Linux konsolunda: kill -SIGQUIT 92102
Alexey

6

Daha yeni yaptım:

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

İşçilerin listesini aldım.

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

... burada n, istenmeyen çalışanın sıfır tabanlı indeksidir.


2

Redis'in DB'yi geçersiz (çalışmayan) çalışanlar içeren diske kaydetmesiyle ilgili benzer bir sorun yaşadım. Redis / resque her başlatıldığında ortaya çıktılar.

Bunu kullanarak düzeltin:

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

Redis'i ve Yeniden Başlatma çalışanlarınızı yeniden başlattığınızdan emin olun.


2

Ana bilgisayar adına göre onları Redis'ten nasıl temizleyebileceğiniz aşağıda açıklanmıştır. Bu, bir sunucuyu devre dışı bıraktığımda ve çalışanlar sorunsuz bir şekilde çıkmadığında başıma geliyor.

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


1

Https://github.com/shaiguitar/resque_stuck_queue/ üzerinde çalışmaya başladıYakın zamanda . Bu, sıkışmış işçilerin nasıl düzeltileceğine dair bir çözüm değil, ancak yeniden takılma / takılma sorununu ele alıyor, bu yüzden bu konudaki insanlar için yararlı olabileceğini düşündüm. README'den:

"Yeniden sıralama belirli bir zaman aralığında işleri çalıştırmazsa, seçtiğiniz önceden tanımlanmış bir işleyiciyi tetikler. Bunu bir e-posta göndermek, çağrı cihazı görevi, daha fazla yeniden çalışan eklemek, yeniden başlatmak, size bir txt göndermek için kullanabilirsiniz. ..sana nasıl uyarsa."

Üretimde kullanıldı ve şu ana kadar benim için oldukça iyi çalışıyor.


0

Ben de burada sıkışmış / eski işçileri bıraktım ya da 'işler' demeliyim, çünkü işçi aslında hala orada ve iyi çalışıyor, sıkışan çatallı süreç.

Bir bash betiği aracılığıyla çatallı işlem "İşleme" yi 5 dakikadan uzun bir süredir sonlandırmanın acımasız çözümünü seçtim, ardından çalışan bir sonrakini sıraya koydu ve her şey devam ediyor

komut dosyama bir göz atın: https://gist.github.com/jobwat/5712437


0

Onları doğrudan redis-cli'den uzaklaştırdım. Neyse ki redistogo.com, heroku dışındaki ortamlardan erişime izin veriyor. Listeden ölü işçi kimliğini alın. Benimki

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

Bu komutu doğrudan redis'de çalıştırın.

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

Redis db'yi perde arkasında ne yaptığını görmek için izleyebilirsiniz.

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"

İkinci son satır çalışanı siler.


İyi bir fikir değil. Bu, Resque'deki kayıt silme kancalarını çağırmaz, başarısızlık ve insanların sahip olabileceği olası temizleme kodunu çağırmaz.
Jeremy

Bu, 2 yıl önce arayüzü kullanarak silinmesi imkansız olan sıkışmış işleri gösterdiği ve bunu raylarda yapmanın temiz bir yolu olmadığı zaman geri çekilmesinde yararlıydı
Andrei R

0

Resque'in daha yeni sürümlerini kullanıyorsanız, dahili API'ler değiştiği için aşağıdaki komutu kullanmanız gerekecektir ...

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

0

Bu, 1.26.0'dan daha yeni bir yeniden başlatma sürümüne sahip olduğunuz sürece sorunu önler:

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

Şu anda çalışan işin bitmesine izin vermediğini unutmayın.


0

tüm rescueişçileri durdurmak için aşağıdaki komutu da kullanabilirsiniz

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

bu bağlantıdan referans

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.