cron ジョブを使用してmanage.py
毎分コマンドを実行するシステムがあります。
問題は、ジョブが 1 分以上かかる場合があり、コマンドの 2 つのインスタンスを同時に実行するのは安全ではないことです。
コマンド自体の別のインスタンスが既に実行されているかどうかを検出して早期に終了させる良い方法はありますか? 同じ目的を達成するためのより良い方法はありますか?
たとえば、django-cronjobs (免責事項: 自分では使用していません) を使用してジョブを登録することもできます。ドキュメントから:
# myapp/cron.py
import cronjobs
@cronjobs.register
def periodic_task():
pass
そして、次を使用します。
$ ./manage.py cron periodic_task
さらに、django-cronjob は、デフォルトで、同時に実行されるジョブのコピーが 1 つだけであることを確認します。
ジョブのロックを処理して複数の実行を防ぐ cronjob ライブラリを使用できます -多重実行の防止
代わりに、ジョブを制御するcelerybeat
代わりに使用できます。オーバーヘッドが増えますが、アプリケーションの一部としてすでにセロリを使用している場合、これはそれほど難しくありません。これは、cron に対する celerybeat の利点は何ですか?cron
Celerybeat
celerybeat
ジョブが既に実行されていることを示すために、どこかに状態を保持する必要があります。このpid
手法は問題ありませんが、別の方法として、セマフォをキャッシュ レベル (Memcache/Redis) またはデータベースに直接実装して使用する方法があります。これは、pid ファイルの管理に使用できる一貫したファイル システムがない場合に特に便利です。例えば。Heroku でアプリを実行しています。
また理想的には、できれば cron ジョブを冪等にするようにしてください。つまり、ジョブが複数回並行して実行されても、副作用はありません。
できることは、コマンドの開始時にコマンドでファイルを作成してから、そのタスク (ジョブの pid を含む) を実行し、コマンドの最後でそのファイルをクリーンアップすることです。
コマンドを実行すると、最初にその pidfile が存在するかどうかを確認する必要があります。もしそうなら、それは仕事をするべきではありません。
そう:
これは完全ではありません (たとえば、コマンドが正しく終了しない場合、pidfile は削除されず、コマンドは二度と実行されません) が、状況には十分な場合があります。
質問も参照してください: pid および lock ファイルとは何ですか?