ฉันจะล้างคนงาน Resque ค้าง / ค้างได้อย่างไร


133

ดังที่คุณเห็นจากภาพที่แนบมาฉันมีคนงานสองสามคนที่ดูเหมือนจะติดอยู่ กระบวนการเหล่านี้ไม่ควรใช้เวลานานเกินสองสามวินาที

ป้อนคำอธิบายภาพที่นี่

ฉันไม่แน่ใจว่าทำไมพวกเขาไม่ล้างหรือวิธีลบออกด้วยตนเอง

ฉันใช้ Heroku โดยใช้ Resque กับ Redis-to-Go และ HireFire เพื่อปรับขนาดคนงานโดยอัตโนมัติ


2
สวัสดีคำถามกึ่ง ๆ : คุณได้รับ resque-web dashboard ผ่าน heroku ได้อย่างไร? ฉันคิดไม่ออกว่าจะเปิดอย่างไร
Aaron Marks

คำตอบ:


215

วิธีแก้ปัญหาเหล่านี้ไม่ได้ผลสำหรับฉันฉันจะยังคงเห็นสิ่งนี้ใน redis-web:

0 out of 10 Workers Working

ในที่สุดสิ่งนี้ได้ผลสำหรับฉันในการล้างคนงานทั้งหมด:

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

12
สิ่งนี้ได้ผลสำหรับฉัน มันไม่ได้ลงทะเบียนคนงานทั้งหมดซึ่งค่อนข้างน่ารำคาญ แต่สิ่งนี้ตามมาด้วยheroku restartดูเหมือนจะทำเคล็ดลับ ตอนนี้แสดงจำนวนคนงานที่ถูกต้อง
Brian Armstrong

สิ่งนี้นำคนงานออกจากอินเทอร์เฟซทางเว็บ แต่จริงๆแล้วพวกเขายังคงแสดงเป็นกระบวนการและยัง "ขโมย" งานจากคิว
txwikinger

20
หากคุณต้องการยกเลิกการลงทะเบียนเฉพาะคนงานที่ไม่ใช่กระบวนการจริง (และอาจกำลังประมวลผลงาน) คุณอาจต้องการลองResque.workers.each {|w| matches = w.id.match(/^[^:]*:([0-9]*):[^:]*$/); pid = matches[1]; w.unregister_worker unless w.worker_pids.include?(pid.to_s)}ซึ่งจะยกเลิกการลงทะเบียนเฉพาะคนงานเหล่านั้นที่ pids ไม่ได้เป็นส่วนหนึ่งของ pids ทำงานที่รู้จัก ฉันไม่รู้ว่ามันใช้ได้ในทุกสภาพแวดล้อมหรือเปล่า แต่มันใช้ได้ดีกับ ubuntu สิ่งนี้อาจใช้ได้เฉพาะเมื่อคนงานของคุณอยู่บนเครื่องเดียวกับที่คุณเรียกใช้รหัสนี้
roychri

3
เป็นตัวเลือก Resque.workers.map &: unregister_worker
AB

เหตุใดจึงไม่รวมการตรวจสอบว่าควรยกเลิกการลงทะเบียนคนงานก่อนโทรunregister_workerหรือไม่ มีวิธีกำหนดสิ่งนี้หรือไม่?
user5243421

53

ในคอนโซลของคุณ:

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

มิฉะนั้นคุณสามารถพยายามปลอมเป็นสิ่งที่ทำเพื่อลบออกโดย:

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

แก้ไข

ผู้คนจำนวนมากโหวตให้คำตอบนี้และฉันรู้สึกว่าสิ่งสำคัญคือผู้คนลองใช้วิธีแก้ปัญหาของ hagope ซึ่งยกเลิกการลงทะเบียนคนงานออกจากคิวในขณะที่รหัสด้านบนจะลบคิว หากคุณพอใจที่จะปลอมมันก็เจ๋ง


3
ถ้าเขาทำแบบนี้มันจะลบคิวทั้งหมดเขาแค่ต้องการเอาคนที่ติดอยู่ออก ..
jBeas

1
การอัปเดตขนาดเล็ก: ตอนนี้คุณต้องใช้ Resque.redis.del แทน Resque.redis.delete
James P McGrath

1
ตอนนี้มีวิธี Resque.remove_queue () แล้ว
iainbeeston

29

คุณอาจติดตั้ง resque gem ไว้เพื่อให้คุณสามารถเปิดคอนโซลและรับคนงานปัจจุบันได้

Resque.workers

ส่งคืนรายชื่อคนงาน

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

เลือกคนงานและprune_dead_workersตัวอย่างเช่นคนแรก

Resque.workers.first.prune_dead_workers

1
อันที่จริงในการลองครั้งที่สองสิ่งนี้ไม่ได้ทำอะไรเลย
Shpigford

2
วิธีนี้ใช้ได้ผลดีในการเคลียร์คนงานที่ถูกต่อต้านที่ถูกฆ่าตายโดยไม่ต้องยกเลิกการลงทะเบียน
Lukas Eklund

3
นี่เป็นคำตอบใหม่ที่ดีที่สุดเนื่องจากไม่ได้ยกเลิกการลงทะเบียนทั้งหมด prune_dead_workers ไม่ควรเป็น class method ใช่หรือไม่? แต่ไม่ว่าในกรณีใดทางออกที่ดี! ขอบคุณ.
Brian Armstrong

นั่นเป็นทางออกสำหรับคนงานที่ถูกฆ่า -9 คน สิ่งเดียวที่ฉันจะเพิ่มคือคุณต้องทำสิ่งนั้นบนเซิร์ฟเวอร์เดียวกันกับที่คุณฆ่าด้วย -9
Stanislav O. Pogrebnyak

ทำกับทุกคนพร้อมกัน: Resque.workers.each (&: prune_dead_workers)
Leo

25

การเพิ่มคำตอบโดย hagope ฉันต้องการที่จะสามารถยกเลิกการลงทะเบียนเฉพาะคนงานที่ทำงานในช่วงเวลาหนึ่งเท่านั้น โค้ดด้านล่างจะยกเลิกการลงทะเบียนเฉพาะคนงานที่ทำงานเกิน 300 วินาที (5 นาที)

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

ฉันมีคอลเลกชันของงาน Rake ที่เกี่ยวข้องกับ Resque อย่างต่อเนื่องซึ่งฉันได้เพิ่มสิ่งนี้ไว้ใน: https://gist.github.com/ewherrmann/8809350


3
จุดแสดงวิธีเข้าถึงเวลาเริ่มงานผ่านการประมวลผล ['run_at'] ฉันเคยเห็นวิธีแก้ปัญหาอื่น ๆ ที่ใช้วิธีการเริ่มต้นแต่สิ่งนี้จะคืนเวลาที่คนงานเริ่มทำงานไม่ใช่งานซึ่งเป็นวิธีการที่ไม่ถูกต้องในการเคลียร์คนงานที่ติดอยู่ ขอบคุณ!
Lachlan Cotter

10

รันคำสั่งนี้ทุกที่ที่คุณรันคำสั่งเพื่อเริ่มต้นเซิร์ฟเวอร์

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

คุณควรเห็นสิ่งนี้:

92102 resque: Processing ProcessNumbers since 1253142769

จด PID (รหัสกระบวนการ) ในตัวอย่างของฉันคือ92102

จากนั้นคุณสามารถออกจากกระบวนการ 1 จาก 2 วิธี

  • ใช้อย่างสง่างาม QUIT 92102

  • บังคับใช้ TERM 92102

*ฉันไม่แน่ใจว่าไวยากรณ์เป็นอย่างใดอย่างหนึ่งQUIT 92102หรือQUIT -92102

โปรดแจ้งให้เราทราบหากคุณมีปัญหาใด ๆ


3
ในคอนโซล Linux: kill -SIGQUIT 92102
Alexey

6

ฉันเพิ่งทำ:

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

มีรายชื่อคนงาน

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

... โดยที่ n คือดัชนีฐานศูนย์ของผู้ปฏิบัติงานที่ไม่ต้องการ


2

ฉันมีปัญหาคล้ายกันที่ Redis บันทึก DB ลงในดิสก์ซึ่งรวมคนงานที่ไม่ถูกต้อง (ไม่ทำงาน) ทุกครั้งที่ Redis / resque เริ่มปรากฏขึ้น

แก้ไขปัญหานี้โดยใช้:

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

ตรวจสอบให้แน่ใจว่าคุณรีสตาร์ท Redis และพนักงาน Resque ของคุณแล้ว


2

นี่คือวิธีที่คุณสามารถกำจัดพวกมันออกจาก Redis ด้วยชื่อโฮสต์ สิ่งนี้เกิดขึ้นกับฉันเมื่อฉันเลิกใช้เซิร์ฟเวอร์และคนงานไม่ได้ออกอย่างสง่างาม

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

2

ฉันพบปัญหานี้และเริ่มดำเนินการตามคำแนะนำจำนวนมากที่นี่ แต่ผมค้นพบสาเหตุที่สร้างปัญหานี้คือการที่ผมได้ใช้อัญมณี Redis-RB 3.3.0 การดาวน์เกรดเป็น redis-rb 3.2.2 ป้องกันไม่ให้คนงานเหล่านี้ติดขัดตั้งแต่แรก


1

ฉันได้ล้างมันออกจาก redis-cli โดยตรง โชคดีที่ redistogo.com อนุญาตให้เข้าถึงจากสภาพแวดล้อมภายนอก heroku รับรหัสผู้ปฏิบัติงานที่เสียชีวิตจากรายการ ของฉันคือ

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

เรียกใช้คำสั่งนี้ใน redis โดยตรง

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

คุณสามารถตรวจสอบ redis db เพื่อดูว่ามันทำอะไรอยู่เบื้องหลัง

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"

บรรทัดสุดท้ายที่สองจะลบผู้ปฏิบัติงาน


ไม่ใช่ความคิดที่ดี สิ่งนี้จะไม่เรียกการยกเลิกการลงทะเบียน hooks ใน Resque ไม่เรียกความล้มเหลวและอาจมีการล้างรหัสที่ผู้คนอาจมี
Jeremy

สิ่งนี้มีประโยชน์กับ resque เมื่อ 2 ปีก่อนเมื่อมีการแสดงงานที่ติดอยู่ซึ่งไม่สามารถลบได้โดยใช้อินเทอร์เฟซและไม่มีวิธีใดที่จะทำได้ในราง
Andrei R

1

เริ่มทำงานบนhttps://github.com/shaiguitar/resque_stuck_queue/เมื่อเร็ว ๆ นี้ ไม่ใช่วิธีแก้ปัญหาคนงานติด แต่เป็นการแก้ปัญหาการแขวน / ติดค้างดังนั้นฉันคิดว่ามันน่าจะเป็นประโยชน์สำหรับคนในกระทู้นี้ จาก README:

"หาก resque ไม่เรียกใช้งานภายในกรอบเวลาที่กำหนดมันจะทริกเกอร์ตัวจัดการที่กำหนดไว้ล่วงหน้าที่คุณเลือกคุณสามารถใช้สิ่งนี้เพื่อส่งอีเมลหน้าที่เพจเจอร์เพิ่มพนักงาน resque เพิ่มเติมรีสตาร์ท resque ส่ง txt .. ก็ตามที่เหมาะกับคุณ "

ถูกนำมาใช้ในการผลิตและทำงานได้ดีสำหรับฉันจนถึงตอนนี้


0

ฉันมีคนงานติดค้าง / ค้างที่นี่ด้วยหรือฉันควรจะพูดว่า 'งาน' เพราะจริงๆแล้วคนงานยังอยู่ที่นั่นและทำงานได้ดีจึงเป็นกระบวนการแยกที่ค้างอยู่

ฉันเลือกวิธีแก้ปัญหาที่โหดร้ายในการฆ่ากระบวนการแยก "การประมวลผล" ตั้งแต่เวลามากกว่า 5 นาทีผ่านสคริปต์ทุบตีจากนั้นคนงานก็วางไข่ในคิวถัดไปและทุกอย่างก็ดำเนินต่อไป

ดูสคริปต์ของฉันได้ที่นี่: https://gist.github.com/jobwat/5712437


0

หากคุณใช้ Resque เวอร์ชันที่ใหม่กว่าคุณจะต้องใช้คำสั่งต่อไปนี้เนื่องจาก API ภายในมีการเปลี่ยนแปลง ...

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

0

วิธีนี้จะหลีกเลี่ยงปัญหาตราบใดที่คุณมี resque เวอร์ชันใหม่กว่า 1.26.0:

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

โปรดทราบว่าจะไม่ปล่อยให้งานที่กำลังดำเนินอยู่เสร็จสิ้น


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.