1

必要なすべての cronjob の全体を保持する cronjobs という MySQL テーブルがあります (たとえば、古い電子メールの削除、プロファイルの年齢の更新など)。すべての cronjob には、cronjob の期限が来た場合に実行される定義済みのコード ブロックがあります (異なる cronjobs に対して異なる間隔を取得しました)。

due cronjobs の実行のために、UNIX crontab によって毎分実行される PHP スクリプトを取得しました (「php -f /path/to/file/execute_cronjobs_due.php」を呼び出す execute_cronjobs_due.sh を呼び出します)。

execute_cronjobs_due.php を実行すると、すべての cronjobs が実行されることがマークされるため、execute_cronjobs_due.php の別の呼び出しによって、同じ cronjobs が既に実行されている並列実行が発生することはありません。

ここでの問題: 実行に 60 秒以上かかる場合がありますが、crontab プログラムは 60 秒後に execute_cronjobs_due.sh を呼び出しません。実際に起こることは、execute_cronjobs_due.sh が、前の crontab の実行の実行の直後に呼び出されることです。また、実行に 120 秒以上かかる場合は、次の 2 つの実行が同時に初期化されます。

タイムライン:

2015-06-15 10:00:00: execute_cronjobs_due.sh の実行 (140 秒かかります)

2015-06-15 10:02:20: execute_cronjobs_due.sh の 2 つの同時実行

正確に同時に実行されるため、selects(実際にはマークされた1回を除外する必要があります)がまったく同時に実行されるため、実行中のcronjobをマークする必要はありません。そのため、更新は、両方が予定されている cronjobs を既に選択した直後に行われます。

cron ジョブが同時に実行されないようにするには、どうすればこの問題を解決できますか? MySQL テーブルロックを使用できますか?

事前にご連絡いただき、誠にありがとうございました。

フレデリック

4

2 に答える 2

0

cron ジョブが同時に実行されないようにするには、どうすればこの問題を解決できますか?

これを解決するには複数の方法があります。それらも役立つかもしれません:

私の提案は、シンプルに保ち、ファイルロックまたはファイル存在チェックのアプローチを使用することです。

MySQL テーブルロックを使用できますか?

はい、しかしそれは少しやり過ぎです。

cronjob ステータス列 (「ToDo、開始済み、完了」または「Todo、実行中、完了」) と PID 列を含む「cronjob 処理テーブル」を使用します。次に、ジョブを選択し、トランザクションを使用してその状態をマークします。これにより、「Todo からのジョブの選択」と「実行中/開始済みのマーク付け」が 1 つのステップで確実に行われます。最終的に、「中央 cronjob 処理スクリプト」の複数の exec がまだ残っている可能性がありますが、処理のためにジョブが複数回選択されることはありません。

于 2015-06-15T09:47:01.983 に答える