我如何清除卡住/陈旧的雷斯克工人?

正如你可以看到从附加的图像,我有一对夫妇的工人,似乎是卡住了。这些过程不会超过几秒钟。

enter image description here

我不知道他们为什么不清除或如何手动删除他们。

我在 Heroku 上使用 Resque 与 Redis-to-Go 和 HireFire 自动缩放工人。

62024 次浏览

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

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

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

你应该看看这个:

92102 resque: Processing ProcessNumbers since 1253142769

请注意我的例子中的 PID (进程 id)是 92102

然后,您可以退出进程1的2种方式。

  • 优雅地使用 QUIT 92102

  • 强制使用 TERM 92102

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

有什么麻烦就告诉我。

在你的控制台:

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

否则,你可以试着假装它们已经被做了,然后移除它们,方法是:

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

剪辑

很多人对这个答案表示赞同,我觉得人们应该尝试一下 hagope 的解决方案,它将工作者从队列中注销,而上面的代码则删除队列。如果你乐意假装,那就好。

这些解决方案对我来说都不管用,我仍然会在 Redis-web 上看到这一点:

0 out of 10 Workers Working

最后,这个方法让我清理了所有的工人:

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

我有一个类似的问题,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。

我在这里也卡住了/陈旧的工人,或者我应该说“工作”,因为工人实际上仍然在那里并且运行良好,是分叉进程卡住了。

我选择了一种残忍的解决方案,即通过 bash 脚本在5分多钟后终止分叉进程“ Processing”,然后工作人员在队列中生成下一个进程,一切继续进行

看看我的剧本: https://gist.github.com/jobwat/5712437

我刚说了:

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

拿到工人名单了。

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

其中 n 是不想要的工人的从零开始的指数。

我已经把它们从 redis-cli 直接清除了,幸运的是 redistogo.com 允许从 heroku 之外的环境访问。 从名单上找出死亡工人的身份,我的是

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

直接运行这个命令。

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

您可以监视 redisdb,以了解它在幕后做什么。

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"

第二行最后一行删除 worker。

最近开始研究 https://github.com/shaiguitar/resque_stuck_queue/。这不是一个解决方案,如何修复卡住的工人,但它解决了问题的规模悬挂/被卡住,所以我认为它可以帮助人们在这个线程。来自 README:

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

已经在生产中使用,目前为止对我来说效果还不错。

通过 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

以下是如何通过主机名从 Redis 中清除它们的方法。这种情况发生在我停用服务器时,工作人员不能优雅地退出。

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

如果您正在使用新版本的 Resque,那么当内部 API 发生变化时,您将需要使用以下命令..。

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

只要你有一个比1.26.0更新的版本,就可以避免这个问题:

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

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

我遇到了这个问题,并开始实施这里的许多建议的道路。然而,我发现造成这个问题的根本原因是我是 使用 gem redis-rb 3.3.0。降级至 redis-rb 3.2.2,从一开始就阻止了这些工人陷入困境。

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

<id>是工人 ID。

docker stop <id>


docker start <id>

在 resque 2.0.0中,这里有一种方法可以使 看起来只移除实际上看起来死亡的工人:

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

我不是这方面的专家,可能有更好的方法来解决这个问题。我也在想办法。

这似乎可以移除那些没有发送“心跳”的工作人员,他们的时间比 工作人员名单预期的要长得多。

如果幻象工作者处于“运行”状态,那么在“失败”作业队列中将创建一个与幻象作业相对应的新条目。