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

发布于 2024-12-04 19:04:36 字数 209 浏览 0 评论 0原文

正如您从附图中看到的,我有几个工人似乎被困住了。这些过程不应超过几秒钟。

在此处输入图像描述

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

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

As you can see from the attached image, I've got a couple of workers that seem to be stuck. Those processes shouldn't take longer than a couple of seconds.

enter image description here

I'm not sure why they won't clear or how to manually remove them.

I'm on Heroku using Resque with Redis-to-Go and HireFire to automatically scale workers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

夏至、离别 2024-12-11 19:04:36

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

0 out of 10 Workers Working

最后,这对我清除所有工作人员有用:

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

None of these solutions worked for me, I would still see this in redis-web:

0 out of 10 Workers Working

Finally, this worked for me to clear all the workers:

Resque.workers.each {|w| w.unregister_worker}
☆獨立☆ 2024-12-11 19:04:36

在你的控制台中:

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

否则你可以尝试假装它们已完成删除它们,方法是:

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

编辑

很多人都赞成这个答案,我觉得人们尝试 hagope 的解决方案注销很重要工作人员离开队列,而上面的代码删除队列。如果你乐意伪造它们,那就酷了。

In your console:

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

Otherwise you can try to fake them as being done to remove them, with:

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

EDIT

A lot of people have been upvoting this answer and I feel that it's important that people try hagope's solution which unregisters workers off a queue, whereas the above code deletes queues. If you're happy to fake them, then cool.

很酷又爱笑 2024-12-11 19:04:36

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

You probably have the resque gem installed, so you can open the console and get current workers

Resque.workers

It returns a list of workers

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

pick the worker and prune_dead_workers, for example the first one

Resque.workers.first.prune_dead_workers
听风念你 2024-12-11 19:04:36

添加到 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

Adding to answer by hagope, I wanted to be able to only unregister workers that had been running for a certain amount of time. The code below will only unregister workers running for over 300 seconds (5 minutes).

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

I have an ongoing collection of Resque related Rake tasks that I have also added this to: https://gist.github.com/ewherrmann/8809350

苏辞 2024-12-11 19:04:36

无论您在何处运行启动服务器的命令,都可以运行此命令,

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

您应该会看到如下内容:

92102 resque: Processing ProcessNumbers since 1253142769

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

然后您可以退出进程 1 of 2方式。

  • 优雅地使用QUIT 92102

  • 强制使用TERM 92102

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

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

Run this command wherever you ran the command to start the server

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

you should see something like this:

92102 resque: Processing ProcessNumbers since 1253142769

Make note of the PID (process id) in my example it is 92102

Then you can quit the process 1 of 2 ways.

  • Gracefully use QUIT 92102

  • Forcefully use TERM 92102

* I'm not sure of the syntax it's either QUIT 92102 or QUIT -92102

Let me know if you have any trouble.

一身软味 2024-12-11 19:04:36

我刚刚做了:

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

得到了工人名单。

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

...其中 n 是不需要的工人的从零开始的索引。

I just did:

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

Got the list of workers.

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

... where n is the zero based index of the unwanted worker.

樱娆 2024-12-11 19:04:36

我遇到了类似的问题,Redis 将数据库保存到包含无效(未运行)工作线程的磁盘。每次启动 Redis/resque 时,它​​们都会出现。

使用以下方法修复此问题:

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

确保重新启动 Redis 和 Resque 工作线程。

I had a similar problem that Redis saved the DB to disk that included invalid (non running) workers. Each time Redis/resque was started they appeared.

Fix this using:

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

Make sure you restart Redis and your Resque workers.

梨涡 2024-12-11 19:04:36

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

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

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

Started working on https://github.com/shaiguitar/resque_stuck_queue/ recently. It's not a solution to how to fix stuck workers but it addresses the issue of resque hanging/being stuck, so I figured it could be helpful for people on this thread. From README:

"If resque doesn't run jobs within a certain timeframe, it will trigger a pre-defined handler of your choice. You can use this to send an email, pager duty, add more resque workers, restart resque, send you a txt...whatever suits you."

Been used in production and works pretty well for me thus far.

入怼 2024-12-11 19:04:36

以下是如何通过主机名从 Redis 中清除它们。当我停用服务器并且工作人员无法正常退出时,就会发生这种情况。

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

Here's how you can purge them from Redis by hostname. This happens to me when I decommission a server and workers do not exit gracefully.

Resque.workers.each { |w| w.unregister_worker if w.id.start_with?(hostname) }
不如归去 2024-12-11 19:04:36

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

I ran into this issue and started down the path of implementing a lot of the suggestions here. However, I discovered the root cause that was creating this issue was that I was using the gem redis-rb 3.3.0. Downgrading to redis-rb 3.2.2 prevented these workers from getting stuck in the first place.

醉城メ夜风 2024-12-11 19:04:36

我直接从 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"

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

I've cleared them out from redis-cli directly. Luckily redistogo.com allows access from environments outside heroku.
Get dead worker ID from the list. Mine was

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

Run this command in redis directly.

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

You can monitor redis db to see what it's doing behind the scenes.

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"

Second last line deletes the worker.

小姐丶请自重 2024-12-11 19:04:36

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

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

我不是正在发生的事情的专家,可能有更好的方法这样做或者那样做就会有问题。我也只是想弄清楚这个问题。

这似乎从 resque 工作人员列表中删除了比预期时间长得多的时间没有发送“心跳”的工作人员。

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

In resque 2.0.0, here's one way that seems to work to remove only actually appearantly-dead workers in resque 2.0.0:

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

I am not an expert in what's going, it's possible there's a better way to do this or that this will have problems. I'm just trying to figure this out too.

This seems to remove workers that haven't sent a "heartbeat" in much longer than expected from the resque worker list.

If the phantom worker was in a "running" state, then a new entry in the "failed" job queue will be created corresponding to phantom job.

一花一树开 2024-12-11 19:04:36

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

我选择了残酷的解决方案,即通过 bash 脚本终止分叉进程“处理”超过 5 分钟,然后工作进程只是在队列中生成下一个进程,一切都会继续进行,

请查看我的脚本:https://gist.github.com/jobwat/5712437

I had stuck/stale resque workers here too, or should I say 'jobs', because the worker is actually still there and running fine, it's the forked process that is stuck.

I chose the brutal solution of killing the forked process "Processing" since more than 5min, via a bash script, then the worker just spawn the next in queue, and everything keeps on going

have a look at my script here: https://gist.github.com/jobwat/5712437

左秋 2024-12-11 19:04:36

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

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

If you are using newer versions of Resque, you'll need to use the following command as the internal APIs have changed...

Resque::WorkerRegistry.working.each {|work| Resque::WorkerRegistry.remove(work.id)}
梦毁影碎の 2024-12-11 19:04:36

只要您有比 1.26.0 更新的 resque 版本,这就可以避免该问题:

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

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

This avoids the problem as long as you have a resque version newer than 1.26.0:

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

Keep in mind that it does not let the currently running job finish.

千纸鹤带着心事 2024-12-11 19:04:36

如果你使用Docker,也可以使用这个命令:

是worker id。

docker stop <id>

docker start <id>

If you use Docker, you can also use this command:

<id> is the worker id.

docker stop <id>

docker start <id>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文