バッチ処理が重複するのを避ける方法
例えば、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使って止めてみました。
これで、出力結果をファイルに吐き出すように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が交互に出力されてるのが分かります。