Jenkinsで重いジョブと一緒に動かしたくない&特定の日時でしか実行したくないとき
小ネタですが、どなたかのかゆいところに手が届けばと思い、投稿します。
前提
- Jenkinsでサービスのジョブ実行を制御している
- バッチサーバーのリソースは諸事情により簡単に増やせない
といった方々にご一読頂けたら嬉しい内容です。
要件
- 特定の重いジョブ("Heavy Job" とします)とは一緒に動いてほしくない
- 1日1回、特定の時間帯しか動かしたくない
この2つの要件を満たすにはどうすればいいのかを考えた場合、
まず単純にHeavy Jobの下流として指定する方法が思い浮かぶのですが、
Heavy Jobが1日に複数回動くケースでは、2つ目の要件(1日1回、特定の時間帯しか動かしたくない)を満たすことができません。
ではクーロンで日時を指定して動かせば・・・となりますが、Heavy Jobはその名の通り重いジョブなので、実行時間が想定よりも延びてしまう可能性があります。
その場合、処理内容によっては一緒に動いてしまうと、バッチサーバのマシンリソースを食い合うことによって、OOMなど深刻な問題に陥いる可能性が生まれ、結果お互いのジョブ及び他の実行中ジョブにも影響を与えてしまいます。
どうすればよいか?
やり方は色々あるかと思いますが、自分が対応したのはこういったやり方です。
- Heavy Jobの下流で動くように設定 → 要件1を満たす
- 特定の時間帯のみ実行されるように制御する(下記例では0〜3時) → 要件2を満たす
#!/bin/sh -e hour=`date -d "9hours" "+%k"` hour=`echo $hour | tr -d " "` echo "現在" $hour "時" # 0〜3時のみ実行 if [ $hour -ge 4 ]; then echo "AM0〜3時以外は実行しない" exit 0 fi … # ここからジョブで実現したいことを書く
解説
Build → Execute shell にて時間帯制御のロジックを書きます。
hour=`date -d "9hours" "+%k"`
-d "9hours"
オプションで9時間後の日付を取得することができます。
UTC環境で動く前提ですが、JSTとの差は+9時間なのでこのようにしています。
"+%k"
はフォーマット指定です。0〜23の時間の数値で、1桁の場合はスペースが入ります。
これによって hour
には JST での0〜23の数値が入ります。
hour=`echo $hour | tr -d " "`
次に、先程取得したhourの整形です。
tr
コマンドで半角スペースを削除します。
if [ $hour -ge 4 ]; then echo "AM0〜3時以外は実行しない" exit 0 fi
最後に、greater than or equal(>=)の意味を持つ -ge
を条件に、実行したくない時間だったら exit 0
で抜けるようにしています。
解説は以上です。どなたかのご参考になれば幸いです。