Browse Tag: cron

crontab で環境変数を使う方法

crontab にたくさんの同じようなバッチ処理を書く場合、環境変数を使うのが便利です。各バッチ処理で、同じ環境変数名でかつ値が違う環境変数を設定するためにどうすればよいのかなぁと調べたところ、crontabで環境変数を使う際に知っておきたいたった1つのこと – (゚∀゚)o彡 sasata299’s blog を見つけました。ここでは env を使っていますが、なぜか CentOS 5 系ではうまくいきませんでした。

いろいろと試行錯誤したところ、次のような感じで値が違う同じ環境変数を設定することができました。


MAILTO=root
RUBY=/usr/local/bin/ruby

ROOT_DIR=/home/naoya/app1
RAILS_ENV=production
0 0 * * * cd $ROOT_DIR; $RUBY script/runner

ROOT_DIR=/home/naoya/app2
RAILS_ENV=test
0 1 * * * cd $ROOT_DIR; $RUBY script/runner

こんな感じで設定すると、バッチはその上に書かれている環境変数の値となって実行することができます。

  1. 00:00: ROOT_DIR=/home/naoya/app1, RAILS_ENV=production
  2. 01:00: ROOT_DIR=/home/naoya/app2, RAILS_ENV=test

ちなみに Puppet で設定すると、上と同じ設定内容になります。
上の記述の方が、env を使うよりもすっきりとバッチ処理を記述できるので、いいと想っています。

cron の直列実行

久しぶりのブログになります。

cron でとあるバッチ処理を setlock を使って、毎時順番に直列実行しています。

このバッチ処理は、過去 1 時間前のアクセスログをごにょごにょ集計しています。仮に、このバッチ処理は、1.rb、2.rb、3.rb、の 3 つのプログラムがあるとしましょう。2.rb は、必ず 1.rb が実行し終わったあとに実行することを前提、3.rb は、必ず 2.rb が実行し終わったあとに実行することが前提となっています。

cron には、次のように 5 分刻みで設定されています。

5 */1 * * * /usr/bin/setlock /tmp/hoge.lock /tmp/1.rb

10 */1 * * * /usr/bin/setlock /tmp/hoge.lock /tmp/2.rb

15 */1 * * * /usr/bin/setlock /tmp/hoge.lock /tmp/3.rb

それぞれのプログラムの最初には、過去 1 時間前を取得する、次のようなコードが書かれています。

target_date = DateTime.now.ago(60 * 60)

この状態で、1.rb から 3.rb まで、すべて 1 時間以内で終了すれば問題がないのですが、1 時間以上かかってくると、当然ながら問題が出てきます。

1 時間以上かかっても大丈夫なように、それぞれのプログラムに対象の日時を渡すように変更して、次のように cron を変更しました。

5 */1 * * * /usr/bin/setlock /tmp/hoge.lock /tmp/1.rb –date `/bin/date –date ‘1hours ago’ +\%Y-\%m-\%d`

10 */1 * * * /usr/bin/setlock /tmp/hoge.lock /tmp/2.rb –date `/bin/date –date ‘1hours ago’ +\%Y-\%m-\%d`

15 */1 * * * /usr/bin/setlock /tmp/hoge.lock /tmp/3.rb `–date /bin/date –date ‘1hours ago’ +\%Y-\%m-\%d`

これで、毎時のタスクがどんなに時間がかかっても、毎時間の処理が正しく行われることになります。

ここまでくると cron の設定が複雑になってしまうので、まとめたシェルスクリプトを書くか、バッチプログラムをまとめてもいいかもしれません。

今のところ、それほど毎時実行する cron は多くないので、しばらくこれで様子をみようと思います。