Cron jobok monitorozása: a heartbeat minta a gyakorlatban
· 6 perc olvasás
A HTTP monitorozás nem észleli, hogy egy éjszakai cron elhasalt. A heartbeat minta megfordítja az irányt: a cron jelentkezik a monitorozásnál, és ha nem hív be időben, értesítést kapsz.
A probléma: háttérfeladatok HTTP endpoint nélkül
Egy tipikus backendnek több útvonala van:
- Webes kérések (HTTP/HTTPS a szerverre) - ezeket uptime check-kel monitorozod.
- Cron jobok (napi mentés, havi számlázás, óránkénti szinkronizáció) - nincs HTTP endpointjuk, a külső monitorozás nem tudja figyelni őket.
- Workerek (Celery, BullMQ, Sidekiq), amelyek egy sort dolgoznak fel - szintén HTTP nélkül.
Amikor egy cron elhasal (elgépelés a crontabban, tele lemez, hiányzó környezeti változó (environment variable) vagy importálási hiba egy függőség frissítése (dependency upgrade) után), senki nem értesít. Hétfő reggel jössz rá, amikor észreveszed, hogy a hétvégén egyetlen számlát sem küldött ki a rendszer.
A heartbeat minta: a cron pingeli a monitorozást
Az elv fordított a normál monitorozáshoz képest:
- A monitorozó szolgáltatásban létrehozol egy heartbeat monitort egy elvárt intervallummal (például "60 percenként").
- Kapsz egy egyedi heartbeat URL-t:
https://epulz.io/heartbeat/abc123xyz. - A cron jobodban, egy sikeres futás végén, meghívod ezt az URL-t (HTTP GET vagy POST).
- Ha a ping nem érkezik meg az elvárt időn belül (plusz türelmi időszak), a monitorozás értesít.
Gyakorlati példa: heartbeat egy cron jobból
# /etc/crontab
0 3 * * * www-data /usr/local/bin/backup.sh && curl -fsS -m 10 \
https://epulz.io/heartbeat/abc123xyz > /dev/null
A kulcs az && operátor: a heartbeat csak akkor megy ki, ha a backup.sh 0 kilépési kóddal fejeződik be. Ha a szkript elhasal, a ping nem érkezik meg, és egy órán belül értesítést kapsz.
Tipp: Alaposabb lefedettségért adj hozzá egy "start" heartbeatet is:
curl -fsS -m 10 https://epulz.io/heartbeat/backup-start-xyz > /dev/null
/usr/local/bin/backup.sh && \
curl -fsS -m 10 https://epulz.io/heartbeat/backup-done-xyz > /dev/null
A monitorozás így meg tudja különböztetni az "elindult, de nem fejeződött be" (a szkript lefagyott) esetet a "soha nem indult el" (a cron job le sem futott) esettől.
Python: requests + try/except
import os, requests
HEARTBEAT_URL = os.environ["HEARTBEAT_URL"]
def sync_data():
# ... your logic ...
pass
try:
sync_data()
requests.get(HEARTBEAT_URL, timeout=10)
except Exception as e:
# A heartbeat nem megy ki - a monitorozás értesít
raise
Node.js: async / await
const HEARTBEAT_URL = process.env.HEARTBEAT_URL;
async function nightlyJob() {
await processInvoices();
await fetch(HEARTBEAT_URL, { signal: AbortSignal.timeout(10000) });
}
nightlyJob().catch(err => {
console.error(err);
process.exit(1);
});
Türelmi időszak: mennyi időt adj az értesítés előtt
A heartbeat monitornak szüksége van bizonyos toleranciára. A cron időnként a szokásosnál tovább fut, a hálózatnak van késleltetése, és az NTP szinkronizáció kissé eltolódhat. A türelmi időszak az az idő az elvárt intervallum letelte után, amíg a monitorozás még vár, mielőtt értesítést indít.
Gyakorlati értékek:
- Óránkénti cron: intervallum 60 perc + türelem 10 perc
- Napi mentés (átlagosan 20 perc): intervallum 1440 perc + türelem 60 perc
- Heti report: intervallum 10080 perc + türelem 360 perc (6 ó)
Túl szűk türelem = hamis értesítések (false positive). Túl laza = késleltetett értesítés pont akkor, amikor a feladat valóban elhasal.
Hol segít a legtöbbet a heartbeat minta
- Éjszakai DB mentések
- Szinkronizáció külső API-kkal (CRM, accounting, payment)
- Report kalkulációk
- Cleanup feladatok (régi munkamenetek, logok, ideiglenes fájlok törlése)
- Hosszan futó workerek healthcheck ciklusa
- Ütemezett e-mailek, hírlevelek, számlázás
Konklúzió
A háttérfeladatok (background) gyakran kritikusabbak, mint maga a weboldal, mégis a monitorozás vakfoltjai maradnak. A heartbeat minta megvalósítása mindössze öt percet vesz igénybe (csak adj egy curl-t a cron sor végére), és ugyanazt a biztonságot adja, mint a frontend uptime monitorozása.
Gyors emlékeztető: cron szintaxis
A heartbeat hibák többsége valójában cron hiba - a ping soha nem fut le, mert rossz volt az ütemezés. Az öt mező:
┌── perc (0-59)
│ ┌── óra (0-23)
│ │ ┌── a hónap napja (1-31)
│ │ │ ┌── hónap (1-12)
│ │ │ │ ┌── a hét napja (0-7, 0 és 7 = vasárnap)
│ │ │ │ │
* * * * * parancs
| Kifejezés | Lefut |
|---|---|
*/5 * * * * |
5 percenként |
0 * * * * |
minden óra elején |
0 3 * * * |
minden nap 03:00-kor |
0 3 * * 1 |
minden hétfőn 03:00-kor |
30 2 1 * * |
a hónap első napján 02:30-kor |
A klasszikus csapda: a */5 az óra mezőben nem azt jelenti, hogy "mostantól 5 óránként", hanem az öttel osztható órákat (0, 5, 10, 15, 20). Ha a monitor elvárt intervalluma és a valós cron ütemezés nem egyezik, fantom értesítéseket kapsz.
A "dead man's switch" elv
A heartbeat minta egy dead man's switch (holtember-kapcsoló): a riasztás a csend. Ez megfordítja a szokásos hibamódot. A normál monitorozás csendben is elhasalhat - ha maga a monitorozó szerver esik ki, egyszerűen abbahagyja az értesítések küldését, és te sosem tudsz róla. A heartbeat ennek az ellentéte: az értesítés kiváltója egy elvárt jelzés hiánya, így egy olyan feladat, amely teljesen leáll (az egész szerver ki van kapcsolva, a cron démon tiltva van, a gépet leselejtezték és elfelejtették), pontosan az az eset, amelyet a legjobban elkap.
A cronon túl: más ütemezők
A minta ugyanaz, függetlenül attól, mi indítja a feladatot:
- systemd timerek - add a curl-t az ExecStart lánchoz vagy az ExecStartPost=-hoz. Párosítsd az OnCalendar= timert egy megfelelő heartbeat intervallummal.
- Kubernetes CronJob - a konténer utolsó lépése pingeli a heartbeat URL-t. Ha a pod elhasal vagy egyáltalán nem ütemeződik (rossz node selector, image pull hiba), a ping hiányzik, és értesítést kapsz.
- Windows Task Scheduler - fejezd be a feladatot az Invoke-WebRequest -Uri $env:HEARTBEAT_URL -TimeoutSec 10 PowerShell paranccsal.
- CI / ütemezett pipeline-ok - egy éjszakai GitHub Actions vagy GitLab schedule utolsó lépésként pingelheti a heartbeatet, megerősítve, hogy a pipeline lefutott és át is ment.
Gyakori anti-minták
- Ping az elején, nem a végén. A munka előtt küldött heartbeat csak azt bizonyítja, hogy a feladat elindult. Tedd a munka mögé, sikerhez kötve (
&&), hogy egy futás közbeni összeomlás szintén visszatartsa a pinget. - A kilépési kód figyelmen kívül hagyása. A
backup.sh; curl ...(pontosvessző) akkor is elküldi a pinget, ha a mentés elhasalt. Mindig&&-t használj. - A curl hibák csendes elnyelése. A
-fsShatására a curl HTTP hiba esetén hangosan elhasal, így a feladatod logjai megmutatják, hogy a heartbeatet nem sikerült kézbesíteni (hálózati probléma a gépen). - Egy heartbeat tíz feladatra. Ha öt cron egy URL-en osztozik, nem tudod, melyik állt le. Adj minden ütemezett feladatnak saját heartbeatet. Ha ugyanahhoz a szolgáltatáshoz HTTP endpointot is kiteszel, párosítsd a heartbeatet egy szokásos uptime check-kel és egy port ellenőrzéssel a worker portján, hogy lefedd a "a folyamat fut" és a "az ütemezett futás megtörtént" esetet is.
Konkrét forgatókönyv: a néma mentési hiba
A heartbeat tankönyvi esete így néz ki. Egy éjszakai pg_dump egy csatolt kötetre ír. Hónapokig működik. Aztán a kötet megtelik, a pg_dump nem nulla kóddal lép ki, és mivel a cron sor sima pontosvesszőt használt, a heartbeat mégis kimegy, és a dashboard zöld marad. Három héttel később az adatbázis sérült, és nincs használható mentés, mert minden "sikeres" mentés azóta, hogy a lemez megtelt, nulla bájtos fájl volt.
A heartbeat minta ezt már az első éjszaka elkapja, de csak ha helyesen van bekötve: kösd a pinget &&-hez, hogy a nem nulla kilépés visszatartsa, és fontold meg a kimenet ellenőrzését is, ne csak a kilépési kódét. Egy mentési szkript kiléphet 0 kóddal, és mégis csonka fájlt állíthat elő. Egy védekezőbb sor ellenőrzi, hogy a dump nem triviális, még a siker jelzése előtt:
/usr/local/bin/backup.sh && \
test "$(stat -c%s /backups/db.sql.gz)" -gt 1000000 && \
curl -fsS -m 10 https://epulz.io/heartbeat/abc123xyz > /dev/null
Most a heartbeat csak akkor érkezik meg, ha a szkript sikeres volt és az eredményfájl több mint 1 MB. Bármi kisebb, és a ping visszatartódik, te pedig a türelmi időszakon belül kapsz értesítést három hét múlva helyett.
Kezdd el monitorozni a cron jobokat
Az ePulz.io támogatja a heartbeat check-eket konfigurálható türelmi időszakkal. 7 nap ingyen.
Kapcsolódó
Próbálja ki az ePulz.io-t ingyen - 7 nap bankkártya nélkül.
Fiók létrehozása