الـ cron بيجدوِل المهام، بس ما بيقولّكش لما واحدة منها فشلت. الموضوع ده بيتحول لكارثة لمّا الـ backup يوقف أسبوعين وانت فاكره شغّال، وتكتشف يوم ما قاعدة البيانات تقع. الدليل ده بيحل المشكلة دي في 15 دقيقة بسكربت bash واحد و Healthchecks.io.
ليه الـ cron jobs بتفشل في صمت؟
خلّيني أبدأ بمثال حقيقي. عندك سيرفر VPS فيه cron بيعمل backup يومي الساعة 3 فجرًا. كتبته مرة واحدة، شغّلته، اتأكدت إنه بيعمل نسخة، ونسيت الموضوع. بعد 6 شهور، الـ script اتكسر لأن كلمة سر الـ database اتغيّرت وما حدّش حدّث ملف .env. الـ cron نفّذ المهمة كل يوم، فشل كل يوم، وما قال لحد. يوم ما احتجت الـ backup، لقيت آخر نسخة ناجحة من 6 شهور.
ده اللي بيحصل فعلاً: الـ cron بينفّذ السطر اللي إنت طالبه، ولو السطر رجّع exit code 1، الـ cron بيدوّن في /var/log/syslog وبس. مفيش إيميل (إلا لو معمول إعداد MTA)، مفيش تنبيه، مفيش لوحة. الـ cron بيديك جدولة من غير visibility.
المفهوم العلمي: Heartbeat Monitoring (Dead Man's Switch)
الحل الصحيح اسمه Heartbeat Monitoring، أو "مفتاح الرجل الميت". المبدأ بسيط: بدل ما الخدمة تسأل "هل أنت مصاب؟"، الخدمة بتستنى منك إشارة كل فترة. لو الإشارة ما جتش، معناها إن في مشكلة.
تخيّل إنك بتكلم صاحبك كل يوم الساعة 10 صباحًا. لو يوم ما كلّمكش، هتقلق. ده بالظبط اللي Healthchecks.io بيعمله: بتقوله "هيوصلك HTTP request من الـ job بتاعي كل 24 ساعة، مع تسامح 30 دقيقة". لو ما وصلش، بيبعت تنبيه.
الخطوات التنفيذية — 15 دقيقة من الصفر لإنتاج
- روح
healthchecks.ioواعمل حساب مجاني. الخطة المجانية بتغطّي حتى 20 check، وده بيكفي غالبية المشاريع الصغيرة والمتوسطة. - اعمل check جديد. حدّد الـ schedule (كرون expression زي
0 3 * * *) و Grace Time (المدة المسموحة قبل التنبيه). - خُد الـ ping URL اللي هيظهرلك. شكله
https://hc-ping.com/UUID. - وصّل الـ URL ده بـ notification channel: Telegram، Discord، Slack، إيميل، أو SMS.
- عدّل سكربت الـ cron بتاعك عشان يعمل ping بعد النجاح فقط.
السكربت الكامل — backup مع heartbeat
#!/usr/bin/env bash
set -euo pipefail
PING_URL="https://hc-ping.com/your-uuid-here"
BACKUP_DIR="/var/backups/postgres"
DATE=$(date +%Y-%m-%d)
# ping start signal — بيسجّل إن الـ job بدأ
curl -fsS -m 10 --retry 3 "$PING_URL/start" > /dev/null
# المهمة الفعلية
pg_dump -U postgres mydb | gzip > "$BACKUP_DIR/backup-$DATE.sql.gz"
# رفع على S3
aws s3 cp "$BACKUP_DIR/backup-$DATE.sql.gz" "s3://my-backups/"
# ping success — بس لو وصلنا لهنا من غير أخطاء (بفضل set -e)
curl -fsS -m 10 --retry 3 "$PING_URL" > /dev/nullالنقطة المهمة: set -euo pipefail بيوقف السكربت عند أول فشل، فالـ ping الأخير ما بيتبعتش إلا لو كل الخطوات نجحت. لو حبيت ترسل إشارة فشل صريحة، استخدم $PING_URL/fail.
أضف فخاخ الإنتاج الحقيقية
لو الـ job بتاعك ممكن يتأخر أو ياخد وقت متغيّر، Grace Time محتاج تظبيط. لو الـ backup عادة بياخد 5 دقائق، حدّد Grace Time بـ 10 دقائق على الأقل. كمان لو عندك jobs حساسة زي معالجة مدفوعات، فعّل خاصية "ping start" قبل المهمة و "ping success" بعدها. كده بتعرف المدة الفعلية لكل تنفيذ.
الأرقام الفعلية والـ trade-offs
- تكلفة: صفر دولار حتى 20 check. بعدها، خطة Supporter بـ 5 دولار شهريًا لـ 50 check.
- زمن تنفيذ إضافي: ~200ms لكل ping (طلب HTTP). ده لا شيء بالنسبة لـ job بياخد دقيقتين.
- موثوقية: الخدمة عندها uptime أعلى من 99.9%. لو قلقان، تقدر تستضيف نسخة self-hosted بـ Docker.
- المكسب: بتعرف في خلال دقائق لو job فشل، بدل ما تكتشف بعد أسابيع.
- التكلفة الخفيّة: dependency على خدمة خارجية. لو الـ firewall بتاعك بيحجب traffic خارج، محتاج استثناء لـ
hc-ping.com.
متى لا تستخدم Healthchecks.io
لو الـ job بتاعك بيتنفّذ كل ثانية (زي high-frequency traders) أو بيحتاج تتبع دقيق لكل خطوة جوا المهمة، Healthchecks.io مش الحل. استخدم Prometheus مع Pushgateway، أو نظام مراقبة مدمج زي Sentry Cron Monitoring. كمان لو بيئتك air-gapped (مفصولة عن الإنترنت)، استضف نسخة self-hosted.
الخطوة التالية
افتح crontab بتاعك دلوقتي: crontab -l. اختار أهم job عندك (الـ backup على الأرجح)، اعمل check على Healthchecks.io، وعدّل السكربت يبعت ping. لو خلال أسبوع وصلك تنبيه فشل، اعرف إنك وفّرت على نفسك كارثة. لو مفيش تنبيهات، زوّد باقي الـ jobs تدريجيًا.