cron をそのまま使っていると、複数台のサーバーで同じタイミングにジョブが起動してしまい、 意図せず負荷が集中するケースがあります。
このような「同時実行による負荷集中」を避けるために、cron ジョブの実行タイミングに ランダムな遅延(ジッター)を加えたい場合があります。
例えば、以下のように実行している cron ジョブにジッターを加えたいとします。
# vi /etc/cron.d/app
*/15 * * * * root cd /usr/app; php artisan user-function
cron の標準機能でできないか調べる
まず、cron 自体にランダム遅延の機能が無いかを確認します。
anacronにはRANDOM_DELAYというパラメータが存在する- しかし、一般的な
cronには同等の機能は用意されていない
そのため、標準機能だけでジッターを加えることはできません。
自前でやる方法を考える
Laravel 側で sleep を入れる
Artisan コマンドの処理の冒頭でランダムな遅延を入れる方法です。
public function handle()
{
sleep(rand(0, 120)); // 0〜120秒の間でランダムに遅延
$this->userFunction();
}
アプリケーション側の制御になるため、実装が簡単という利点があります。
シェルスクリプトで sleep を入れる
cron からシェルスクリプトを呼び出し、その中でランダムな遅延を加える方法です。
# vi /root/bin/run_user_function.sh
#!/bin/bash
cd /usr/app
sleep $((RANDOM % 121)) # 0〜120秒
php artisan user-function
chmod 755 /root/bin/run_user_function.sh
cron 側の設定を以下のように変更します。
# vi /etc/cron.d/app
*/15 * * * * root /root/bin/run_user_function.sh
crontab にワンライナーで書く場合
シェルスクリプトを用意せず、ワンライナーで記述することも可能です。
# vi /etc/cron.d/app
*/15 * * * * root cd /usr/app; sleep $((RANDOM \% 121)); php artisan user-function
cron の設定ファイル内では % をエスケープする必要がある点に注意してください。