ブログ

cronジョブがサイレントに失敗する理由 — そしてその見つけ方

システム cron はジョブが成功したかどうかわかりません。スケジュールされたジョブが痕跡なく失敗する理由と、それを修正するパターン。

SteadyCron cronreliabilitymonitoring

特定の種類の障害は、派手な障害よりもたちが悪いです: サイレントな障害です。スケジュールされたジョブが動かなくなり、何もアラートが来ず、数週間後に被害を発見します — 空のバックアップ、一度も発火しなかった請求処理、凍結した状態の検索インデックス。この投稿はなぜそれが起こるのか、そしてどうすれば止められるかについてです。

cron は発火して忘れる

根本的な問題は Unix の cronスーパーバイザーではなくランチャーだということです。定刻にコマンドを実行して次に移ります。コマンドが0で終了したか1で終了したか、永遠にハングしたか、スタックトレースを出力したかは関知しません。成功、失敗、「1時間前に動くべきだったが動かなかった」という概念は組み込まれていません。

そのため依存関係がダウンしている、認証情報が期限切れ、ディスクがいっぱい、デプロイがパスを変えたなど、あらゆる通常の方法でジョブが失敗しても、cron の観点では何も起きていません。

誰も検知しない3つの失敗モード

  1. 動いたが失敗した。 スクリプトが開始したがゼロ以外で終了した。cron は気づかず、せいぜい誰も読まないルートのローカルメールボックスにメールを送るだけです。
  2. ハングした。 ジョブが開始して完了せず、ロックを保持するかメモリをリークし続けています。次のスケジュールの実行が開始しないこともあります。
  3. まったく動かなかった。 サーバーが再起動した、crontab が誤って編集された、夏時間でタイムゾーンがずれた。ジョブが単純に発火しておらず、欠如は気づきにくい最も難しい状態です。

最初の2つはジョブが結果を報告する必要があります。3つ目はそのボックス上では検出できません。なぜなら教えてくれるはずのものが壊れているからです。

修正: ハートビートと実行記録

2つのパターンでギャップを埋めます。

ハートビートは「動いたか?」という質問をダウンしているかもしれないマシンから切り離します。ジョブが完了したとき外部サービスに ping し、ping がスケジュール通りに届かない場合サービスがアラートを送ります。重要なのは、これが「まったく動かなかった」ケースも検出することです — サイレンスがシグナルです。

# ジョブの末尾に
curl -fsS https://ping.steadycron.com/<your-ping-token>

実行記録は各実行の結果(ステータス、所要時間、出力)をキャプチャします。「午前3時のジョブは成功したか、何を返したか?」という質問に数日後でも答えられます。

SteadyCron の役割

SteadyCron は両方を行います。リトライとタイムアウト付きで HTTP ジョブを実行し、すべての実行を記録し、すでに動いている cron をハートビートで監視します — 実行漏れ、失敗、スタックした実行をメール、Slack、Discord、Telegram、webhook でアラートします。

ダッシュボードではなく顧客から壊れたジョブの報告を受けたことがあれば、それが私たちが解決するために作った問題です。

無料で始めるか、ハートビート監視ガイドを読んでください。