הגדרת משימות רקע מבוזרות (עובדים מרובים)
מבוא: מדוע עובד יחיד הוא סיכון
דמיינו שעובד יחיד מעבד אלף משימות בדקה. לפתע הוא קורס—התור גדל, מיילים מפסיקים להישלח, ההמרה נעצרת. ללא שכפול והפצה, אתם מאבדים נתונים. בפרויקט עם שיא של 12,000 משימות בדקה, פרסנו 8 עובדים על 4 שרתים עם Redis והקטנו את זמן הביצוע הממוצע מ-40 ל-8 שניות. משימות רקע מבוזרות אינן רק שכפול עובדים—הן דורשות ארכיטקטורה מחושבת: אידמפוטנטיות, נעילות, ניטור.
בעיות שאנו פותרים
אובדן משימות בקריסת עובד
ללא שכפול תור, משימה נתקעת. הברוקר מחזיק הודעות, ו-retry_after מחזיר אותן לתור. עם retry_after נכון (גדול מזמן הקצוב המקסימלי של המשימה), אובדן נתונים מסולק.
שאילתות N+1 למסד נתונים
עובד יחיד מעבד משימות ברצף, מה שמגדיל את זמן הביצוע. עובדים מרובים מקבילים את העומס. בפרויקט עם 50 עובדים, ראינו ירידה בזמן העיבוד מ-3 דקות ל-12 שניות.
מבוי סתום בגישה מקבילית
שני עובדים יכולים לקחת את אותה משימה. אנו פותרים זאת עם נעילות מבוזרות באמצעות Redis SET NX PX. נעילה עם TTL של 120 שניות מבטיחה שמשימה מבוצעת בדיוק פעם אחת.
מדוע Redis נבחר לעיתים קרובות לתורים?
Redis מהיר פי 3 מ-RabbitMQ בפעולות push/pop ואינו דורש הגדרת exchange. עבור Laravel Horizon, הוא הכלי הטבעי. RabbitMQ מציע ניתוב מורכב (fanout, topic)—נחוץ אם משימות מחולקות לתורים בעלי עדיפויות שונות. אבל עבור 90% מהפרויקטים, Redis מספיק.
| ברוקר | תפוקה | מורכבות | ניתוב | אמינות |
|---|---|---|---|---|
| Redis | 100k הודעות/שנייה | נמוכה | פשוט | Redis Sentinel/Cluster |
| RabbitMQ | 50k הודעות/שנייה | בינונית | Fanout, Topic | Cluster עם מראות |
| SQS | 10k הודעות/שנייה | גבוהה | מוגבל | מנוהל AWS UDP |
לפרטים נוספים, ראו את התיעוד הרשמי של Redis.
כיצד להגדיר retry_after נכון?
retry_after הוא קריטי: הוא חייב להיות גדול מזמן הקצוב של המשימה. עבור המרת וידאו, הגדירו 3600; עבור קמפיינים במייל, 180; עבור בקשות API, 90. ערך קטן מזמן הקצוב יגרום לביצוע חוזר של המשימה לפני סיומה.
כיצד להבטיח אידמפוטנטיות?
עם עובדים מבוזרים, משימה בודדת עשויה להתבצע פעמיים (אם עובד קורס לאחר שלקח אותה). השתמשו בנעילות מבוזרות:
class ProcessPaymentJob implements ShouldQueue {
public function handle(): void {
$lock = Cache::lock("payment:{$this->paymentId}", 120);
if (!$lock->get()) {
$this->release(10);
return;
}
try {
if ($payment?->status !== 'pending') return;
$this->processPayment($payment);
} finally {
$lock->release();
}
}
}class ProcessPaymentJob implements ShouldQueue { public function handle(): void { $lock = Cache::lock("payment:{$this->paymentId}", 120); if (!$lock->get()) { $this->release(10); return; } try { if ($payment?->status !== 'pending') return; $this->processPayment($payment); } finally { $lock->release(); } } } משתמש ב-Redis SET NX PX—נעילה אטומית.
הפרדת עובדים לפי סוג עומס
הריצו עובדים לתורים שונים על שרתים נפרדים. לדוגמה:
- שרתי API: תורים
Cache::lock(),critical - שרת מדיה (עם GPU):
default,transcoding - דוחות רקע:
media,batch,reports
הגדרת Supervisor על שרת המדיה:
[program:media-worker]
command=php /var/www/artisan queue:work --queue=transcoding,media --timeout=3600 --max-jobs=1
numprocs=2
autostart=true
autorestart=true
user=www-data
stopwaitsecs=3600low חייב להיות לפחות זמן הקצוב המקסימלי של המשימה; אחרת, תהליכים נהרגים במהלך פריסה.
השוואת תצורות לפי סוג תור:
| סוג תור | זמן קצוב | retry_after | מספר עובדים |
|---|---|---|---|
| critical | 90 | 120 | 4 |
| default | 300 | 360 | 8 |
| transcoding | 3600 | 3700 | 2 |
| batch | 600 | 650 | 1 |
ניטור והתראות
לניטור בריאות העובדים, הקמנו Prometheus ו-Grafana: ייצוא אורך תור, זמן ביצוע, מספר ניסיונות חוזרים. בהתבסס על מדדים, ניתן להגדיל או להקטין עובדים אוטומטית באמצעות HPA ב-Kubernetes. Laravel Horizon מספק לוח מחוונים מוכן, אך לייצור, אנו ממליצים על Prometheus + Alertmanager—שליחת התראות ל-Telegram/Slack כאשר התור גדל או עובדים נכשלים.
דוגמה להגדרת Prometheus exporter לתורים
השתמשו ב-`phpredis-exporter` או בחבילת Laravel ייעודית לייצוא מדדי תור Redis. ב-Kubernetes, הגדירו ServiceMonitor כך ש-Prometheus יאסוף מדדים אוטומטית.שלבי עבודה
- ניתוח: לימוד העומס, בחירת ברוקר (Redis/RabbitMQ), תכנון מבנה התורים. איסוף מדדי תור נוכחיים.
- הקמת תשתית: פריסת הברוקר (Redis Cluster או RabbitMQ), הגדרת ניטור (Prometheus, לוח מחוונים של Horizon).
- יישום: הגדרת עובדים, נעילות מבוזרות, אידמפוטנטיות. כתיבת בדיקות לביצוע מקבילי.
- בדיקות: סימולציה של קריסות עובדים, בדיקת מדדים, בדיקת מבוי סתום. דחיפת 1000 משימות ב-30 שניות.
- פריסה: הגדרת Supervisor, HPA (אם Kubernetes), השקת Horizon. תוכנית גיבוי מוכנה תוך פחות מדקה.
מה כלול
- תיעוד על הגדרת ברוקר ועובדים.
- גישה לניטור (לוח מחוונים של Horizon, Prometheus).
- הדרכת צוות: כיצד להוסיף תורים חדשים, לטפל בתקלות.
- שבועיים של תמיכה לאחר ההשקה.
לוח זמנים ועלות
הגדרה בסיסית (Redis + Horizon על שני שרתים) — יום אחד. עם נעילות מבוזרות ואידמפוטנטיות — עד יומיים. אינטגרציה עם Kubernetes HPA — פרויקט נפרד של 1–2 ימים. העלות מחושבת באופן אישי. ספרו לנו על הפרויקט שלכם—צרו קשר.
אנו מבטיחים: מעל 5 שנות ניסיון, 50+ פרויקטים עם תורים מבוזרים, אפס משימות אבודות. קבלו ייעוץ—תארו את העומס שלכם, ואנו נציע ארכיטקטורה. צרו קשר לדיון מפורט.







