如何清除卡住/陈旧的Resque工作人员?

时间:2011-09-14 12:28:48

标签: ruby-on-rails ruby-on-rails-3 heroku redis resque

从附图中可以看出,我有几个似乎被卡住的工人。这些过程不应超过几秒钟。

enter image description here

我不确定他们为什么不清除或如何手动删除它们。

我正在Heroku使用Resque with Redis-to-Go和HireFire来自动扩展工作人员。

17 个答案:

答案 0 :(得分:212)

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

0 out of 10 Workers Working

最后,这有助于我清除所有工人:

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

答案 1 :(得分:49)

在你的控制台中:

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

否则你可以尝试将它们伪装成删除它们,并使用:

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

修改

很多人一直在赞同这个答案,我觉得人们尝试hagope的解决方案是非常重要的,该解决方案会将工作人员从队列中取消注册,而上述代码会删除队列。如果你很高兴假装它们,那就很酷。

答案 2 :(得分: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

答案 3 :(得分: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

答案 4 :(得分:9)

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

$ ps -e -o pid,command | grep [r]esque
你应该看到这样的事情:

92102 resque: Processing ProcessNumbers since 1253142769

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

然后你可以退出2种方法中的过程。

  • 优雅地使用QUIT 92102

  • 强行使用TERM 92102

* 我不确定它的语法是QUIT 92102还是QUIT -92102

如果您有任何问题,请告诉我。

答案 5 :(得分:6)

我刚刚做了:

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

获得了工人名单。

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

...其中n是不需要的工人的零基础索引。

答案 6 :(得分: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 worker。

答案 7 :(得分:2)

我遇到了这个问题,开始在这里实施很多建议。但是,我发现创建此问题的根本原因是我using the gem redis-rb 3.3.0。降级到redis-rb 3.2.2可以防止这些工人陷入困境。

答案 8 :(得分:2)

以下是如何通过主机名从Redis中清除它们的方法。当我退役服务器并且工作人员没有正常退出时,这种情况发生在我身上。

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

答案 9 :(得分:1)

最近开始致力https://github.com/shaiguitar/resque_stuck_queue/。它不是如何解决卡住工人的解决方案,但它解决了resque挂起/被卡住的问题,所以我认为它可能对这个线程上的人有所帮助。来自README:

“如果resque在特定时间范围内没有运行作业,它将触发您选择的预定义处理程序。您可以使用它来发送电子邮件,寻呼机职责,添加更多resque工作人员,重新启动resque,发送给您一个txt ......任何适合你的东西。“

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

答案 10 :(得分:0)

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

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

直接在redis中运行此命令。

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

您可以监控redis数据库,看看它在幕后做了什么。

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"

倒数第二行删除了工作人员。

答案 11 :(得分:0)

如果您使用较新版本的Resque,则需要使用以下命令,因为内部API已更改...

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

答案 12 :(得分:0)

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

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

请记住,它不会让当前正在运行的作业完成。

答案 13 :(得分:0)

我在这里也遇到了过时的工作人员,或者我应该说'工作',因为工人实际上还在那里并且运行良好,这是分叉的过程被卡住了。

我选择了杀死分叉进程“处理”的残酷解决方案,因为超过5分钟,通过bash脚本,然后工作人员只是在队列中生成下一个,并且一切都在继续

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

答案 14 :(得分:0)

您还可以使用以下命令停止所有rescue工作人员

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

reference from this link

答案 15 :(得分:0)

如果使用Docker,也可以使用以下命令:

<id>是工作人员ID。

docker stop <id>

docker start <id>

答案 16 :(得分:0)

在 resque 2.0.0 中,这是一种似乎的方法,可以在 resque 2.0.0 中移除实际上已经死亡的工人:

Resque::Worker.all_workers_with_expired_heartbeats.each { |w| w.unregister_worker }

我不是正在发生的事情的专家,可能有更好的方法来做到这一点,或者这会出现问题。我也在想办法解决这个问题。

这似乎从 resque worker 列表中删除了比预期更长的时间没有发送“心跳”的 worker。

如果 phantom worker 处于“running”状态,那么“failed”作业队列中会创建一个新的 entry 对应于phantom job。