バッチ処理が重複するのを避ける方法

2011/04/27

例えば、1分毎に走らせてるバッチ処理があり、1分後にまだその処理が終わってない場合、同じ処理が重複して実行されてしまいます。これを避ける方法として、同じ処理が走ってるかどうかチェックする機能を実装しました。

バッチ処理の重複実行を回避するシェルスクリプト

シェルスクリプトがphpファイルを実行する例(このソースはgistでも管理しています。)

#!/bin/sh
exec_file='/full/path/to/exec_file_name.php'
pid=`pgrep -f $exec_file`

#if not running
if [ -z $pid ] ; then
        echo "Done!!"
        php $exec_file
#don't exec
else
        echo "canceled"
fi

ポイントは、pgrepコマンドで、実行ファイル名を含んでいる処理のプロセスIDを取得していること。マッチしない場合は、空になるので、if内の条件が真になり実行されます。

また、文字列によるあいまい検索なので、実行ファイル名(exec_file)はフルパスを推奨します。

検証方法

動作の検証ですが、実行するphp内でsleep使って止めてみました。

<?php
echo date('Ymd H:i:s')."\n";
//100秒とめます。1分以上(2分以内で)であればおけ。
sleep(100);
?>

これで、出力結果をファイルに吐き出すようにcronに設定して、

 */1 * * * * sh /path/to/test.sh 1>> /tmp/test.php.1.log

出力結果が以下のようになったので、OKかな。

・・・
Done!!
20110427 16:38:01
canceled
Done!!
20110427 16:40:01
canceled
Done!!
20110427 16:42:01
canceled
・・・

Done!! とcanceledが交互に出力されてるのが分かります。

コメントを残す

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