スタックした/古いResqueワーカーをクリアするにはどうすればよいですか?


132

添付の画像からわかるように、行き詰まっているように見える労働者が何人かいます。これらのプロセスに数秒以上かかることはありません。

ここに画像の説明を入力してください

なぜクリアされないのか、手動で削除する方法がわかりません。

私はHerokuで、Resque-to-GoとHireFireでResqueを使用して、ワーカーを自動的にスケーリングしています。


2
こんにちは、準関連の質問:herokuを介してresque-webダッシュボードをどのように入手しましたか?開け方がわからないようです。
アーロンマークス

回答:


215

これらの解決策のどれも私にとってうまくいきませんでした、私はまだこれをredis-webで見るでしょう:

0 out of 10 Workers Working

最後に、これは私にとってすべての労働者を排除するのに役立ちました:

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

12
これでうまくいきました。それは少し迷惑だったすべての労働者の登録を解除しました。しかし、これに続いheroku restartてトリックを行うように見えました。正しい数のワーカーが表示されるようになりました。
Brian Armstrong

これにより、Webインターフェースからワーカーが
削除

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が既知の実行中のpidの一部ではないワーカーのみを登録解除することをお勧めします。これがすべての環境で機能するかどうかはわかりませんが、ubuntuではうまく機能します。これは、ワーカーがこのコードを実行するのと同じマシン上にある場合にのみ機能する可能性があります。
roychri 2013

3
オプションとしてResque.workers.map&:unregister_worker
AB

これには、呼び出す前にワーカー登録解除する必要があるかどうかのチェックが含まれていないのはunregister_workerなぜですか?これを決定する方法はありますか?
user5243421

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.deleteの代わりにResque.redis.delを使用する必要がある
James P McGrath

1
Resque.remove_queue()メソッドが実際にあります
iainbeeston '16年

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
実際、2回目の試行では、これは何もしませんでした。
Shpigford、2011

2
これは、登録を解除せずに殺されたレスキュー労働者を片付けるのに最適です。
Lukas Eklund

3
すべての登録を解除するわけではないので、これは新しいベストアンサーのようです。prune_dead_workersをクラスメソッドにしないでください。しかし、いずれにしても、素晴らしい解決策です!ありがとう。
ブライアンアームストロング

それは間違いなく、殺された-9人の労働者のための解決策です。私が追加する唯一のものは、あなたが-9で殺したのと同じサーバーでそれをする必要があるということです。
スタニスラフO.ポグレブニャック2013年

それらすべてに対して一度にそれを行います:Resque.workers.each(&:prune_dead_workers)
Leo

25

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
processing ['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つの方法のうちの1つで終了できます。

  • 優雅に使う 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が無効な(実行されていない)ワーカーを含むディスクにDBを保存するという同様の問題がありました。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) }

2

私はこの問題に遭遇し、ここで多くの提案を実装する道を歩み始めました。ただし、この問題を引き起こしている根本的な原因は、gem redis-rb 3.3.0を使用していることであることがわかりました。redis-rb 3.2.2にダウングレードすることで、これらのワーカーが最初から行き詰まるのを防ぎました。


1

https://github.com/shaiguitar/resque_stuck_queue/で作業を開始最近で。これはスタックしたワーカーを修正する方法の解決策ではありませんが、resqueがハングする/スタックする問題に対処するため、このスレッドの人々に役立つと考えました。READMEから:

「resqueが特定の時間内にジョブを実行しない場合、選択した定義済みのハンドラーがトリガーされます。これを使用して、電子メールの送信、ポケットベルの義務、resqueワーカーの追加、resqueの再起動、txtの送信を行うことができます。 ..あなたに合ったものなら何でも。」

プロダクションで使用されており、これまでのところかなりうまく機能しています。


0

私もここでスタック/古くなったレスキューワーカーがいました、または「ジョブ」と言ったほうがいいでしょう。ワーカーは実際にまだそこにいて正常に実行されているため、フォークされたプロセスがスタックしています。

私は5分以上、bashスクリプトを使用して、フォークされたプロセス「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"

最後の2行目はワーカーを削除します。


良い考えではありません。これはResqueの登録解除フックを呼び出さず、失敗や呼び出しコードのクリーンアップを呼び出しません。
ジェレミー

これは、インターフェースを使用して削除することが不可能でスタックされたジョブを示していた2年前のresqueで役に立ちました。レールでそれを行うクリーンな方法がありませんでした
Andrei R

0

Resqueの新しいバージョンを使用している場合は、内部APIが変更されているため、次のコマンドを使用する必要があります...

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

0

1.26.0より新しいresqueバージョンを持っている限り、これにより問題が回避されます。

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

現在実行中のジョブが終了しないことに注意してください。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.