cron実行スクリプトの多重起動防止ワンライナー

cron実行スクリプトの多重起動防止ワンライナー、これでええやん

ジョブの多重実行問題

よくこんな感じで1分おきにジョブを流したい場合があると思う。

ところがこのcron_job.rbが1分以内に処理が終わらない場合、1分後には同じスクリプトが2重で起動されてしまう。

これは良くないので、多重起動の防止策が必要ねというのがそもそもの課題。

多重実行防止方法

cron_job.rbの内部ロジックとして、多重実行を防ぐ

ジョブのスクリプト内に、DBのstatusカラム(0:未実行, 1:実行中, 2:実行完了)を作成して、statusを参照することで多重起動防止する。

というような施策を行うことがあるが、これが機能しないとバグになるし、ジョブ起動の管理はスクリプト本体からは切り離したい。というかそもそも毎回そんな処理を書き足すのが面倒くさい。

cron_job.rbプロセスの実行状況を確認して、多重実行を防ぐ

こういうケースではジョブの実行開始時にロックファイルを作成して、ロックファイルがあったら後追いのcronでは実行しちゃだめよーという方法がポピュラーらしいが、なんか面倒に感じる。

ということで、簡単な方法を求めていたら、pidofコマンドを使ってジョブの実行状況を確認する方法だとワンライナー的に書けて一番便利そう。これでええやん。

ワンライナーの説明

  • 「||」の左辺がプロセスの実行状況確認、右辺が実際のスクリプト。
  • pidofは-xオプションを付けないと、自作スクリプトなどのプロセスの存在を検出してくれない。
  • pidofはプロセスが1つ以上存在する場合は0以外のリターンコードを返す。
  • 「||」は左辺が0意外なら右辺を実行する

一応テストしてみる

処理終了に1分以上(70秒)かかるスクリプトを作成した。

多重実行防止「無し」で試す

これを1分おきのcronで定期実行し、ジョブの開始と終了をlogに保存する。

多重実行防止があれば同じプロセスID(pid)のstart, endが交互に来るはず。

が、crontabに多重実行防止の処理を入れてないので結果は以下のようにあちゃーとなる。別プロセスIDのstartとstartが連続して続いていることから、思いっきり2重に起動している。

多重実行防止「有り」で試す

ここで、例のcron多重起動防止ワンライナーを使ってみる。これでどーでしょー!!

一点注意なのはcron実行ユーザーの環境変数のせいか、pidofをcronで使うと、そんなコマンドは無いと怒られます。たぶんパスが通ってないようです。なので、crontabでpidofを使う際は、/usr/sbin/pidofと絶対パスで指定してください。

結果は素晴らしい!きちんと同じプロセスIDのstart, endが交互に来てます。多重実行が防止できていることがわかる。

簡単につかえて、これでええやん。( ´_ゝ`)ノ

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です