Назад в блог

Как мониторить cron-задачи: 5 паттернов с heartbeat

· 7 мин чтения

Cron-задачи падают молча. Пять heartbeat-паттернов - от dead man's switch и обёртки exit-кода до grace-окон - чтобы узнать о сбое первыми.

Как мониторить cron-задачи: 5 паттернов с heartbeat

Cron прекрасно запускает вещи по расписанию и катастрофически плох в том, чтобы сообщить, когда этого не сделал. Резервная копия, которая перестала выполняться, редко выдаёт ошибку, которую вы увидите. Она просто молча ничего не делает, и вы узнаёте об этом недели спустя, когда копия нужна, а её нет. Это проблема тихого сбоя, и именно поэтому каждая важная плановая задача нуждается в heartbeat-проверке.

Heartbeat (или "dead man's switch") переворачивает логику. Вместо того чтобы оповещать, когда что-то не так, ваша задача пингует мониторинговый endpoint, когда всё в порядке. Если ожидаемый пинг не приходит вовремя, монитор оповещает. Нет пинга - нет новостей - большая проблема.

Ниже - пять паттернов, от простейшего до самого надёжного. Все предполагают, что у вас есть heartbeat URL из вашего инструмента мониторинга.

Паттерн 1: Классический dead man's switch

Простейшая возможная настройка. Ваша задача после завершения вызывает URL. Если монитор в ожидаемом окне не получает сообщения, он оповещает.

# Ежедневный бэкап в 02:30, пинг после завершения
30 2 * * * /usr/local/bin/backup.sh && curl -fsS https://ваш-монитор/ping/abc123

Важна &&: curl запускается только если backup.sh завершился кодом 0 (успех). Если бэкап падает, пинг не отправляется и монитор это ловит. Флаги -fsS заставляют curl при HTTP-ошибках падать тихо, но реальные проблемы всё же показывать.

Слабость: подтверждает лишь то, что скрипт выполнялся и завершился нулём. Если скрипт проглатывает свои ошибки и всё равно завершается нулём, вы получаете ложное "всё в порядке."

Паттерн 2: Пинг только при реальном успехе

Сделайте сигнал успеха явным вместо опоры на цепочку exit-кодов в shell. В скриптах с несколькими шагами это нагляднее.

#!/bin/bash
set -euo pipefail   # при любой ошибке падай громко
run_the_backup
verify_the_backup    # реально проверь, что вывод существует и осмыслен
curl -fsS https://ваш-монитор/ping/abc123   # достижимо лишь если всё выше прошло

set -euo pipefail означает, что любая неуспешная команда прервёт скрипт ещё до пинга. Добавление реального шага проверки (файл бэкапа существует, больше нуля байт) закрывает дыру "завершился нулём, но ничего не сделал" из Паттерна 1.

Паттерн 3: Обёртка exit-кода

Когда нельзя изменить саму задачу (сторонний бинарник, вендорский скрипт), оберните её. Обёртка сигнализирует старт, запускает задачу и сообщает exit-код.

#!/bin/bash
URL=https://ваш-монитор/ping/abc123
curl -fsS "$URL/start"                  # сигнал "я запустился"
/opt/vendor/report-generator            # задача, которой вы не управляете
EXIT=$?
curl -fsS "$URL/$EXIT"                   # сообщи exit-код

Сигнал старта позволяет монитору ещё и измерять длительность выполнения и выявлять задачу, которая запустилась, но так и не завершилась (зависла). Сообщение exit-кода даёт ему различать "прошло нормально" и "прошло и упало".

Паттерн 4: Условный пинг (пингуй только когда работа имела смысл)

Некоторые задачи выполняются по расписанию, но реальную работу делают лишь иногда (обработчик очереди, который часто застаёт очередь пустой). Вам не нужно оповещение о "пропавшем heartbeat", когда задача законно ничего не сделала. Пингуйте только тогда, когда реальная работа произошла, и соответственно расширьте расписание.

#!/bin/bash
PROCESSED=$(process_queue)
if [ "$PROCESSED" -gt 0 ]; then
  curl -fsS "https://ваш-монитор/ping/abc123?count=$PROCESSED"
fi

Ожидаемый период монитора установите на самый длинный реальный промежуток между фактическими запусками. Плата - чувствительность: более длинное окно означает более медленное обнаружение, поэтому используйте это лишь когда нерегулярная работа действительно ожидаема.

Паттерн 5: Jitter и grace-окна

Реальные расписания дрейфуют. Задача, назначенная на 02:00, может стартовать в 02:00:04 из-за нагрузки, а длительность ежедневной задачи колеблется. Если монитор ждёт пинг точно в интервале, нормальный jitter поднимет вас зря.

Решение - grace-период: скажите монитору подождать после ожидаемого времени ещё некоторый запас, прежде чем оповещать. Ежедневный бэкап, который обычно длится 8 минут, может использовать 20-минутное grace-окно. Также вам нужен некоторый jitter в самом планировании, когда у вас много задач, чтобы они не нагружали один и тот же ресурс в одну и ту же секунду:

# Добавь небольшую случайную задержку (0-59 c), чтобы разнести задачи на 02:00
0 2 * * * sleep $((RANDOM % 60)) && /usr/local/bin/backup.sh && curl -fsS https://ваш-монитор/ping/abc123

Grace-окна - это разница между монитором, которому вы доверяете, и тем, который вы заглушите после третьей ложной тревоги. Grace задайте так, чтобы он с запасом превышал худшее реальное время выполнения задачи, а не её среднее.

Краткий обзор

Паттерн Лучше всего для Ловит
Dead man's switch Простые задачи с одной командой Задача не запускалась / завершилась ненулём
Пинг при успехе Многошаговые скрипты Тихое "завершился нулём, но ничего не сделал"
Обёртка exit-кода Задачи, которые нельзя изменить Зависания, реальные exit-коды, длительность
Условный пинг Задачи с нерегулярной работой Сбои без ложных "пропавших" оповещений
Jitter и grace Всё с переменным временем выполнения Убирает ложные тревоги от дрейфа

Как внедрить на практике

Начните с Паттерна 1 на самой важной задаче прямо сегодня (бэкап, выставление счетов, синхронизация данных). Добавьте проверку (Паттерн 2) и grace-окно (Паттерн 5), прежде чем начнёте на неё полагаться. Подробное руководство по настройке heartbeat вы найдёте в нашем гайде мониторинг cron-задач через heartbeat.

Если ваша задача общается со службой через конкретный порт, доступность сначала проверьте бесплатной проверкой портов. А когда будете готовы мониторить плановые задачи вместе с сайтами и API в одном месте, посмотрите, как работает мониторинг доступности ePulz.io - 7-дневная пробная версия бесплатна, без карты.

Поделиться: Ссылка скопирована

Попробуйте ePulz.io бесплатно - 7 дней без банковской карты.

Создать аккаунт