如何清除卡住/过时的Resque工作者?


132

如您从所附图像中看到的,我有几个似乎被卡住的工人。这些过程的时间不应超过几秒钟。

在此处输入图片说明

我不确定为什么它们无法清除或如何手动将其删除。

我在Heroku上使用带有Redis-to-Go和HireFire的Resque来自动扩展工作人员。


2
嗨,半相关的问题:您是如何通过heroku获得resque-web仪表板的?我似乎无法弄清楚如何打开它。
亚伦·马克

Answers:


215

这些解决方案都不适合我,我仍然会在redis-web中看到它:

0 out of 10 Workers Working

最后,这对我来说是清除所有工人的工作:

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

12
这对我有用。它取消了所有工人的注册,这有点烦人。但这heroku restart似乎可以解决问题。现在,它显示正确的工人人数。
布莱恩·阿姆斯特朗

这使工作人员从Web界面中消失了,但实际上他们仍然显示为进程,并且还从队列中“偷走”了工作
txwikinger 2013年

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)}仅注销那些不属于已知运行pid的工作程序的工作程序。我不知道这是否适用于所有环境,但是在ubuntu上效果很好。仅当您的工作人员与运行此代码的计算机位于同一台计算机上时,这才可能起作用。
roychri

3
作为一个选项Resque.workers.map:unregister_worker
AB

为什么这不包括在致电之前检查工人是否应该注销的检查unregister_worker?有没有办法确定这一点?
user5243421 2015年

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

28

您可能已安装了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 2012年

3
这似乎是新的最佳答案,因为它不会取消所有注册。prune_dead_workers不应该是一个类方法吗?但是无论如何,这都是很好的解决方案!谢谢。
Brian Armstrong

这绝对是杀死-9名工人的解决方案。我唯一要补充的是,您需要在用-9杀死的同一台服务器上执行该操作。
Stanislav O. Pogrebnyak

立即对所有人执行此操作:Resque.workers.each(&:prune_dead_workers)
Leo

24

除了通过hagope回答外,我希望只能注销已经运行了一定时间的工作人员。以下代码只会取消注册运行时间超过300秒(5分钟)的工作人员。

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

我正在收集与Resque相关的Rake任务,这些任务也已添加到:https : //gist.github.com/ewherrmann/8809350


3
用于显示如何通过处理['run_at']访问作业开始时间的要点。我已经看到了其他使用.started方法的解决方案,但实际上返回的是工作人员开始的时间,而不是工作的时间,这是清除卡住的工作人员的错误方法。谢谢!
Lachlan Cotter 2014年

10

在运行命令以启动服务器的任何地方运行此命令

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

您应该会看到以下内容:

92102 resque: Processing ProcessNumbers since 1253142769

在我的示例中记下PID(进程ID)为92102

然后,您可以退出2种方法之一。

  • 优雅地使用 QUIT 92102

  • 强制使用 TERM 92102

*我不知道语法它要么QUIT 92102QUIT -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将数据库保存到包含无效(未运行)工作程序的磁盘上。每次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) }


1

最近开始在https://github.com/shaiguitar/resque_stuck_queue/上工作。这不是解决卡住的工人的解决方案,但是解决了重新挂起/卡住的问题,因此我认为这可能对从事此工作的人们有所帮助。从自述文件:

“如果resque在特定时间段内没有运行作业,它将触发您选择的预定义处理程序。您可以使用它发送电子邮件,传呼机职责,添加更多resque工作人员,重新启动resque,向您发送txt。 ..最适合你的。”

到目前为止,已用于生产中并且对我来说效果很好。


0

我也曾在这里困住过时的老工人,或者我应该说“工作”,因为该工人实际上仍在那儿并且运转良好,这是一个分叉的过程。

我选择了一种残酷的解决方案,因为它通过bash脚本在5分钟以上的时间内杀死了分叉的进程“ Processing”,然后该工作人员只是在队列中生成了下一个进程,因此一切继续进行

在这里看看我的脚本:https : //gist.github.com/jobwat/5712437


0

我已经直接从redis-cli中清除了它们。幸运的是redistogo.com允许从heroku外部环境进行访问。从列表中获取死亡的工作人员ID。我的是

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"

最后一行删除工作程序。


这不是一个好主意。这将不会在Resque中调用取消注册钩子,不会调用失败以及人们可能拥有的清理代码。
杰里米

这在2年前的resque中很有用,当时它显示卡住的作业,无法使用该界面删除,并且没有干净的方法可以在rails中执行
Andrei R

0

如果您使用的是更高版本的Resque,则由于内部API已更改,因此需要使用以下命令...

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

0

只要您的reque版本高于1.26.0,就可以避免此问题:

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

请记住,它不会使当前正在运行的作业结束。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.