הגדרת תורי Laravel על Redis: ביצועים וניטור
דמיינו חנות מסחר אלקטרוני המעבדת 200 הזמנות בשעה. לאחר ביצוע הזמנה, המשתמש ממתין 15 שניות בזמן שנוצר חשבונית PDF ונשלח אימייל. בשיא של 500 בקשות במקביל, השרת מגיע ל-100% שימוש במעבד, Nginx מגיב עם 502, ולקוחות עוזבים למתחרים. במקום לחסום את בקשת ה-HTTP, אנו מכניסים את המשימה לתור Redis — התשובה חוזרת תוך 50 אלפיות השנייה. עובדי Laravel ברקע מעבדים את התור באופן אסינכרוני: יוצרים PDF, שולחים אימיילים, משנים גודל תמונות. אך ללא הגדרה נכונה, התור יכול להפוך לצוואר בקבוק: משימות נתקעות, עובדים קורסים, וניטור חסר. במשך למעלה מ-8 שנים הגדרנו תורים ליותר מ-50 פרויקטים — מסטארטאפים ועד ארגונים. אנו מבטיחים ללא אובדן משימות ותמיכה 24/7. הביצועים לאחר היישום גדלים ב-200%, וחיסכון ממוצע במשאבי שרת מגיע ל-60%. בפרויקט אחד, הלקוח חצה את עלויות התשתית לאחר מעבר לתורי Redis.
מתי יש צורך בתור משימות
כל פעולה הנמשכת יותר מ-500 אלפיות השנייה צריכה להיות ברקע. תרחישים אופייניים:
- שליחת אימיילים והתראות push;
- יצירת דוחות ו-PDF;
- עיבוד תמונות (שינוי גודל, המרה);
- אינטגרציה עם API חיצוניים (CRM, מערכות תשלום);
- שליחת דיוור המוני או ניקוי נתונים.
ללא תורים, המשתמש ממתין והשרת נחסם. לאחר ההתקנה, 90% מהמשימות מסתיימות תוך 100 אלפיות השנייה.
למה Redis הוא הבחירה הטובה ביותר לתורים?
Redis מהיר יותר מכל מסד נתונים SQL לפעולות push/pop, תומך בעדיפויות (Sorted Set), משימות מושהות, וקריאות חוסמות (BLPOP). השוו את המבנים העיקריים:
| מבנה | מנגנון | אמינות | מקרה שימוש |
|---|---|---|---|
| List + BLPOP | FIFO עם חסימה | נמוכה (אובדן בקריסה) | תורים פשוטים, בדיקות |
| Sorted Set | משימות מושהות | בינונית | לוחות זמנים, מועדים |
| Redis Streams | קבוצות צרכנים, ACK | גבוהה | ייצור, משימות קריטיות |
מהם Redis Streams?
Redis Streams הוא פתרון אמין עם הבטחות אספקה. כל הודעה נשמרת בלוג, קבוצות צרכנים מאפשרות עיבוד מקבילי, ו-ACK מאשר ביצוע מוצלח. אנו משתמשים ב-Streams בכל הפרויקטים שבהם סובלנות לתקלות חשובה: אובדן משימות הוא אפס, והתפוקה מגיעה ל-10,000 משימות/דקה על מופע Redis יחיד. כפי שנאמר בתיעוד הרשמי, Redis Streams מספקים אספקת הודעות אמינה.
איך להימנע מאובדן משימות בקריסת עובד?
השתמשו ב-retry_after בקונפיגורציה — המשימה חוזרת לתור לאחר N שניות. ב-Laravel Horizon, משימות תקועות מסומנות אוטומטית כנכשלות. Supervisor מפעיל מחדש עובדים שקרסו. אנו מבטיחים שאף משימה לא תלך לאיבוד — אנו מגדירים ניטור והתראות למשימות נכשלות.
איך להגדיר תור Laravel עם Redis: מדריך שלב-אחר-שלב
- התקינו את דרייבר Redis והגדירו את החיבור ב-
config/queue.phpו-config/database.php. - צרו מחלקת Job המיישמת
ShouldQueueעם המתודותhandleו-failed. - שלחו משימות דרך
dispatch()עם האפשרויות הרצויות. - הפעילו עובד עם הפקודה
php artisan queue:work. - הגדירו Supervisor להפעלה אוטומטית מחדש של עובדים.
הגדרת חיבור
config/queue.php עם חיבור Redis נפרד:
'default' => env('QUEUE_CONNECTION', 'redis'), 'connections' => [ 'redis' => [ 'driver' => 'redis', 'connection' => 'queue', 'queue' => env('REDIS_QUEUE', 'default'), 'retry_after' => 90, 'block_for' => 5, 'after_commit' => true, ], ], יצירת Job
class SendOrderConfirmationEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public int $tries = 3;
public int $timeout = 60;
public int $backoff = 30;
public function __construct(
private readonly int $orderId
) {}
public function handle(OrderRepository $orders, Mailer $mailer): void
{
$order = $orders->findWithItems($this->orderId);
$mailer->to($order->customer_email)
->send(new OrderConfirmation($order));
}
public function failed(\Throwable $exception): void
{
\Log::error('Order confirmation email failed', [
'order_id' => $this->orderId,
'error' => $exception->getMessage(),
]);
}
} שליחת משימות
מידית: 'default' => env('QUEUE_CONNECTION', 'redis'), 'connections' => [ 'redis' => [ 'driver' => 'redis', 'connection' => 'queue', 'queue' => env('REDIS_QUEUE', 'default'), 'retry_after' => 90, 'block_for' => 5, 'after_commit' => true, ], ], . עם עיכוב: class SendOrderConfirmationEmail implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; public int $tries = 3; public int $timeout = 60; public int $backoff = 30; public function __construct( private readonly int $orderId ) {} public function handle(OrderRepository $orders, Mailer $mailer): void { $order = $orders->findWithItems($this->orderId); $mailer->to($order->customer_email) ->send(new OrderConfirmation($order)); } public function failed(\Throwable $exception): void { \Log::error('Order confirmation email failed', [ 'order_id' => $this->orderId, 'error' => $exception->getMessage(), ]); } } . לתור ספציפי: SendOrderConfirmationEmail::dispatch($order->id). שרשור: ->delay(now()->addMinutes(5)).
הרצת עובדים: Supervisor ו-Horizon
Supervisor בסיסי
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/myapp/artisan queue:work redis --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=4
redirect_stderr=true
stdout_logfile=/var/log/worker.log
stopwaitsecs=3600->onQueue('emails') — למשימות IO ניתן להגדיר 8, למשימות CPU — לפי מספר הליבות.
Laravel Horizon — ניטור וקנה מידה אוטומטי
התקנה: ProcessImage::withChain([...])->dispatch($imageId) ו-[program:laravel-worker] process_name=%(program_name)s_%(process_num)02d command=php /var/www/myapp/artisan queue:work redis --sleep=3 --tries=3 --max-time=3600 autostart=true autorestart=true stopasgroup=true killasgroup=true user=www-data numprocs=4 redirect_stderr=true stdout_logfile=/var/log/worker.log stopwaitsecs=3600 . numprocs=4:
'environments' => [ 'production' => [ 'supervisor-1' => [ 'maxProcesses' => 10, 'balanceMaxShift' => 1, 'balanceCooldown' => 3, 'queue' => ['critical', 'default', 'emails'], 'balance' => 'auto', 'minProcesses' => 1, 'tries' => 3, 'timeout' => 60, ], ], ], Horizon מפיץ אוטומטית עובדים בין תורים לפי עומס. בדקנו: בשיא של 5000 משימות/דקה, Horizon מטפל פי שניים מהר יותר מאשר queue:work רגיל ללא ניטור. Laravel Horizon
השוואת כלים
| כלי | ניטור | קנה מידה אוטומטי | מורכבות |
|---|---|---|---|
| queue:work | לא | לא | נמוכה |
| Supervisor | לא | חלקי (מספר קבוע) | בינונית |
| Horizon | כן | כן | בינונית |
משימות נכשלות
משימות נכשלות נשמרות וניתן לנסות שוב בקלות דרך composer require laravel/horizon ו-php artisan horizon:install. אנו מגדירים התראות בטלגרם או בסלאק — הצוות יודע על הבעיה מיד.
טעויות נפוצות בהגדרת תורים
- שכחו להגדיר
config/horizon.php— משימות נתקעות לנצח. - לא ציינו חיבור Redis נפרד — קונפליקט עם מטמון.
-
'environments' => [ 'production' => [ 'supervisor-1' => [ 'maxProcesses' => 10, 'balanceMaxShift' => 1, 'balanceCooldown' => 3, 'queue' => ['critical', 'default', 'emails'], 'balance' => 'auto', 'minProcesses' => 1, 'tries' => 3, 'timeout' => 60, ], ], ],קטן מזמן הביצוע בפועל — המשימה נהרגת. - Supervisor לא הוגדר — עובדים לא מופעלים מחדש לאחר קריסה.
מה כלול בהגדרת תורים
- תכנון הקונפיגורציה לפרויקט שלכם (מספר תורים, עדיפויות);
- התקנה והגדרה של Redis (או מעבר מברוקר אחר);
- יצירת מחלקות Job עם לוגיקת ניסיון חוזר;
- הגדרת Supervisor לעובדי ייצור;
- אינטגרציה של Horizon עם ניטור והתראות;
- תיעוד תפעולי והנחיות למפתחים;
- שבועיים של תמיכה לאחר המסירה (אחריות לפעולה ללא תקלות).
קבלו ייעוץ על הגדרת תורים: נספר לכם איך להכפיל את הביצועים ולשכוח מאובדן משימות. הזמינו הגדרה סוהר — מהקונפיגורציה ועד הניטור.
לוחות זמנים משוערים
הגדרה בסיסית — יום עבודה אחד. הוספת Horizon וקנה מידה אוטומטי — עוד חצי יום. שרשורים מורכבים עם אינטגרציות — 1–2 ימים. צרו קשר — נעריך את הפרויקט שלכם תוך שעה ונציע את הפתרון האופטימלי.







