【问题标题】:How do I clear stuck/stale Resque workers?如何清除卡住/陈旧的 Resque 工作人员?
【发布时间】:2011-11-16 23:53:50
【问题描述】:

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

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

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

【问题讨论】:

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

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


【解决方案1】:

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

0 out of 10 Workers Working

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

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

【讨论】:

  • 这对我有用。它注销了 all 工人,这有点烦人。但这之后是heroku restart 似乎可以解决问题。它现在显示正确的工人数量。
  • 这将工作人员从 Web 界面中取出,但实际上它们仍然显示为进程,并且还从队列中“窃取”了作业
  • 如果您只想注销不是实际进程的工作人员(也可能是处理作业),您可能想尝试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 不属于已知进程的工作人员运行 pid。我不知道这是否适用于所有环境,但它在 ubuntu 上运行良好。这可能仅在您的工作人员在您运行此代码的同一台机器上时才有效。
  • 作为选项 Resque.workers.map &:unregister_worker
  • 请注意,这不会摆脱工作进程。
【解决方案2】:

在您的控制台中:

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

否则,您可以尝试将它们伪装成已完成删除它们,方法是:

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

编辑

很多人都支持这个答案,我觉得人们尝试使用 hagope 的解决方案很重要,该解决方案将工作人员从队列中注销,而上面的代码会删除队列。如果你乐于伪造它们,那就太酷了。

【讨论】:

  • 如果他这样做会删除整个队列,他只是想删除卡住的那些..
  • 小更新:你现在必须使用 Resque.redis.del 而不是 Resque.redis.delete
  • 现在实际上有一个 Resque.remove_queue() 方法
【解决方案3】:

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

【讨论】:

  • 实际上,在第二次尝试时,这没有任何作用。
  • 这非常适合清除那些在没有取消注册的情况下被杀掉的resque工人。
  • 这似乎是新的最佳答案,因为它不会取消注册所有这些。 prune_dead_workers 不应该是一个类方法吗?但无论如何,很好的解决方案!谢谢。
  • 这绝对是杀死 -9 工人的解决方案。我唯一要补充的是,您需要在使用 -9 杀死的同一台服务器上执行此操作。
  • 一次性对所有人进行:Resque.workers.each(&:prune_dead_workers)
【解决方案4】:

补充 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

【讨论】:

  • 显示如何通过 processing['run_at'] 访问作业开始时间的点。我见过使用 .started 方法的其他解决方案,但这实际上返回了 worker 启动的时间,而不是作业,这是清除卡住的工人的错误方法。谢谢!
【解决方案5】:

在您运行命令启动服务器的任何位置运行此命令

$ 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 92102 还是QUIT -92102

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

【讨论】:

  • 在 Linux 控制台中:kill -SIGQUIT 92102
【解决方案6】:

我刚刚做了:

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

得到工人名单。

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

... 其中 n 是不受欢迎的工人的从零开始的索引。

【讨论】:

    【解决方案7】:

    我有一个类似的问题,Redis 将数据库保存到包含无效(非运行)工作人员的磁盘。每次启动 Redis/resque 时,它​​们都会出现。

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

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

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

    【讨论】:

      【解决方案8】:

      最近开始研究https://github.com/shaiguitar/resque_stuck_queue/。这不是解决卡住工人的解决方案,但它解决了重新挂起/被卡住的问题,所以我认为它可能对这个线程上的人有所帮助。来自自述文件:

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

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

      【讨论】:

        【解决方案9】:

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

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

        【讨论】:

          【解决方案10】:

          我遇到了这个问题,并开始在此处实施许多建议。然而,我发现造成这个问题的根本原因是我是using the gem redis-rb 3.3.0。降级到 redis-rb 3.2.2 可以防止这些工作人员首先陷入困境。

          【讨论】:

            【解决方案11】:

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

            倒数第二行删除worker。

            【讨论】:

            • 不是一个好主意。这不会在 Resque 中调用 unregister 钩子,不会调用失败和可能的清理代码。
            • 这在 2 年前的 resque 中很有用,当时它显示了无法使用界面删除的卡住作业,并且在 rails 中没有干净的方法可以做到这一点
            【解决方案12】:

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

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

            我不是这方面的专家,可能有更好的方法可以做到这一点,或者这会出现问题。我也只是想弄清楚这一点。

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

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

            【讨论】:

              【解决方案13】:

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

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

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

              【讨论】:

                【解决方案14】:

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

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

                【讨论】:

                  【解决方案15】:

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

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

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

                  【讨论】:

                    【解决方案16】:

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

                    &lt;id&gt; 是工作人员 ID。

                    docker stop <id>
                    
                    docker start <id>
                    

                    【讨论】:

                      猜你喜欢
                      • 2015-07-18
                      • 2013-06-09
                      • 2011-07-24
                      • 2016-05-23
                      • 1970-01-01
                      • 2012-01-25
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多