celeryリポジトリの例に基づいたsupervisordconfigファイルを使用していますが、celerydの再起動が発生すると、いくつかの問題が発生します。celeryを再起動した後、ログにエラーメッセージが表示されずにタスク処理がサイレントに停止することがあります。 プロセスはプロセスリストに表示されたままになります。
最後に、プロセスが再起動されると、セロリが監視対象によって管理されていない追加のプロセスを生成し、これがこれらのバグにつながることがあることを理解しました。 そのため、再起動するたびにps
の出力を注意深く監視し、killを使用して追加のプロセスを手動で強制終了しました。
そして今日、本当の理由が見つかったと思います。 'stopwaitsecs'オプションのデフォルトの監視対象値は10秒です。 これは、10秒後にセロリプロセスがTERMではなくKILLシグナルで強制終了されることを意味します。 セロリは殺されるのが好きではないようで、その場合は追加のプロセスを生み出そうとします。
したがって、すべての監視対象の設定例ファイルに「stopwaitsecs = 600」のようなものを追加するとよいと思います(よくある質問から:「TERMを数回試したことがない限り、KILLシグナル(-9)でcelerydを停止しないでください。数回待って、シャットダウンする機会を得ました。」)KILLシグナルでのcelerydの動作を調査します。ドキュメントには、タスクが失われると記載されていますが(多くの場合、許容範囲内です)、問題が発生します。プロセスは少し奇妙です。
KILL
シグナルを受信したときに生成されるプロセスは、確かに奇妙です。 supervisord
の外で使用した場合、その動作は見られません。おそらく、これはそれが原因である可能性がありますか?
setproctitle
モジュールをインストールする場合、セロリはps
のリストでプロセスの種類を報告する必要がありますが、どのようなプロセスが作成されるかを調査するためにそれを行うことができますか?
( easy_install setproctitle
)
タイムアウトを600
に設定するのはおそらく良いことです。 無限大の設定はありますか(時間がかかりすぎる場合は警告が表示される可能性があります)? celeryd
がTERM
(推奨されるシャットダウンシグナル)を介して強制終了されると、メッセージの受信を停止し、現在実行中のタスクが終了するのを待ちます。 そして、ほとんどのアプリケーションでは、実行中の終了は受け入れられないと思います。
プロセスの生成に関しては、setproctitleとプロセスIDの監視が役に立ちました。 プロセススポーンではありません。 親プロセスが強制終了されても、ワーカープロセスは存続します。
これは、手動で強制終了し、タイムアウトがゼロの監視付き再起動のシミュレーションです。
4976 ? Ss 0:00 /usr/bin/python /usr/bin/supervisord --pidfile /var/run/supervisord.pid
5422 ? S 0:01 \_ [celerybeat] --schedule=/var/lib/celery/celerybeat-schedule-nadovmeste --loglevel=INFO
6101 ? Sl 0:00 \_ [celeryd.MainProcess] Running... (--loglevel=INFO)
6108 ? S 0:00 \_ [celeryd.PoolWorker-1]
nadovmeste:~# kill 6101 & kill -9 6101 &
ps -afx:
4976 ? Ss 0:00 /usr/bin/python /usr/bin/supervisord --pidfile /var/run/supervisord.pid
5422 ? S 0:01 \_ [celerybeat] --schedule=/var/lib/celery/celerybeat-schedule-nadovmeste --loglevel=INFO
6867 ? Sl 0:00 \_ [celeryd.MainProcess] Running... (--loglevel=INFO)
6875 ? S 0:00 \_ [celeryd.PoolWorker-1]
6108 ? S 0:00 [celeryd.PoolWorker-1]
kill
とkill -9
の間のこのような人工的なレースでのみこれを再現することができました。 時々労働者はきちんと殺されます。 コンソールからcelerydを開始すると、それを再現することができないため、この問題はスーパーバイザー固有のようです。
何度か試した後、コンソールで起動したスクリプトでこれを再現することができました。
/home/nadovmeste/envs/nadovmeste/bin/python /home/nadovmeste/src/nadovmeste/manage.py celeryd -B --loglevel=INFO&
その後、別のターミナルセッションで:
nadovmeste:~# ps -afx
6450 ? Ss 0:00 \_ sshd: root@pts/2
6452 pts/2 Ss+ 0:00 \_ -bash
9343 pts/2 Sl 0:00 \_ [celeryd.MainProcess] Running... (-B --loglevel=INFO)
9350 pts/2 S 0:00 \_ [celeryd.PoolWorker-2]
9355 pts/2 S 0:00 \_ [celerybeat]
nadovmeste:~# kill 9343 & kill -9 9343
nadovmeste:~# ps -afx
4526 ? Ss 0:00 \_ sshd: root@pts/1
4529 pts/1 Ss 0:00 | \_ -bash
9366 pts/1 R+ 0:00 | \_ ps -afx
6450 ? Ss 0:00 \_ sshd: root@pts/2
6452 pts/2 Ss+ 0:00 \_ -bash
...
9350 pts/2 S 0:00 [celeryd.PoolWorker-2]
9355 pts/2 S 0:00 [celerybeat]
監視対象のドキュメントで警告付きの無限タイムアウトの特別なオプションは見つかりませんでした。 それが私たちが望むものであれば、おそらく非常に大きな数で十分でしょう。
-B
オプションを使用した後でのみ、コンソールで起動したcelerydの問題を再現できたため、これはcelerybeatに関連している可能性があります。
いくつかのセロリタスクをローカルでテストしていて、-Bオプションを使用している場合、ctrl-cを使用してもプロセスが強制終了されないことがあります。
これをローカルで再現することはできません。 ところで、マスターブランチを実行していますか? シャットダウンがハングする可能性のあるバグを修正しました。 これでテストできればいいですね。
はい、最新のマスターブランチを実行しています。 私はあなたのバグ修正コミットを見て、それが役立つことを望んでいましたが、私の場合は役に立たないようです:最新のセロリは同じように動作するようです。 しかし、最初の問題が解決された可能性があります-私はこれを即座に殺すだけでチェックします。 今は手を包むことができません:)ctrl-cの問題は私のセットアップでは再現できません。
したがって、バグレポートは簡略化されています:http: //gist.github.com/401028 。 結果は常に同じです(時々ではありません)。 定期的なタスクと非定期的なタスクがあります。 タスクは単純で、完了するのにそれほど時間はかかりません。 メインプロセスを強制終了した後、子プロセスが存続するのはバグですか? もしそうなら、あなたがそれを再現することができないなら、私は最小限のプロジェクトを提供しようとします。
celerybeatの強制終了動作は興味深いものです。hanging(?)celerybeatプロセスを強制終了すると、hanging(?)ワーカープロセスもシャットダウンします。
@kmike上記のコマンドではまだ再現できません。 私がOSXを使用しているためか、Python 2.5を実行しているためか。 (私は2.6.1を実行しています)
--loglevel=DEBUG?
で実行できます。停止する場所に関する情報を提供できます。
celerybeatプロセスはメインプロセスによって開始されるため、メインプロセスが待機していると想定しています
残りのプールプロセスを強制終了する前にcelerybeatを終了します。
メインプロセスが強制終了されたと思いました。プロセスリストに表示されていません。 ただし、プロセス管理の経験はあまりありません。
私のセットアップはDebianLenny + python2.5でした。
--loglevel = DEBUGを指定してcelerydを実行し、MacBookで再現してみます。
うーん、もちろんその通りです。 これは、ビートプロセスがプールプロセスの所有権を取得するようなものです。
python2.5を使用してDebianLennyで再現しようとしましたが、そこで動作します。
TERMとINTの両方で殺害を試みました。
聞いて、助けてくれてありがとう。
最初の問題は、監視対象のタイムアウトを増やし、バグ修正をコミットすることで解決したと思います。 kill -9
コマンドを使用し、TERMの代わりにKILLシグナルを送信するため、シミュレーションは正しくありませんでした。 TERMを使用すると、シグナルプロセスが適切に強制終了されます。
監視対象はTERM信号を使用するため、すべて問題ないはずです。
しかし、私を少し怖がらせるのは、最初のバグが調査されなかったことです。 再現してお知らせします。
ああ! ごめんなさい。 私はその問題を十分に注意深く読んでいませんでした。 はい! それはあなたがSIGKILLでそれを殺したときに起こることです。 9信号をキャッチできないので、このAFAIKについて私たちにできることは何もありません。
それでもCeleryワーカーの終了で問題が発生する場合は、 stopwaitsecs
を増やす前にstopasgroup=true
を設定してみてください。
最も参考になるコメント
それでもCeleryワーカーの終了で問題が発生する場合は、
stopwaitsecs
を増やす前にstopasgroup=true
を設定してみてください。