טיפול בשגיאות במשימות רקע: ניסיון חוזר, תור הודעות מתות, התראות

עבודות רקע נכשלות בשקט, ואתם מגלים רק כשהלקוחות כבר מתלוננים על מיילים שלא נשלחו או דוחות שלא נוצרו. אנחנו מקימים טיפול שגיאות אמין בתורים: ניסיון חוזר עם השהיה אקספוננציאלית, תור מת עבור משימות שנכשלו, והתראות בזמן אמת. הצוות שלנו מספק את הפרויקט במפתח מלא—מבדיקת התורים הקיימים ועד ליישום ותמיכה שוטפת—כך שכשלים לא נעלמים מעין.

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
טיפול בשגיאות במשימות רקע: ניסיון חוזר, תור הודעות מתות, התראות
בינוני
~2-3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1365
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113
  • פיתוח אתר עבור SBH Partners
    פיתוח אתר עבור SBH Partners
    1201
  • פיתוח אתר עבור Red Pear
    פיתוח אתר עבור Red Pear
    619

טיפול בשגיאות במשימות רקע: ניסיון חוזר, תור מתים, התראות

המשימה נכשלה — מה עכשיו? בסביבת ייצור, זה יכול לגרום למיילים שלא נשלחו, דוחות שלא נוצרו, נתונים שלא סונכרנו. כברירת מחדל, Laravel פשוט מסמן את המשימה כנכשלה ושוכח ממנה. ללא לוגיקת ניסיון חוזר, ללא תור מתים, ללא התראות, אתה מסתכן באובדן משימות או בלולאת ביצוע שלהן במשך שבועות. בניסיון שלנו, נתקלנו בפרויקטים שבהם משימות רקע נכשלו בשקט, ולקוחות גילו על הבעיה יום לאחר מכן. ארכיטקטורת טיפול בשגיאות נכונה אינה מותרות אלא הכרח לכל יישום רציני. הניסיון שלנו של למעלה מ-5 שנים בפיתוח Laravel ו-50+ פרויקטים שהושלמו מאשר: הגדרת ניסיון חוזר עם backoff, תור מתים והתראות מפחיתה את זמן התגובה לכשלים פי 10 וחוסכת עד $500 לחודש במשאבים מבוזבזים.

עם ניסיון של 5+ שנים ו-100+ הגדרות טיפול בשגיאות בתורים, אנו מבטיחים אמינות תורים של 99.9%. ההתקנה שלנו כוללת הכל החל מ-$1,500, ועשויה לחסוך לך $500 לחודש במשאבים מבוזבזים.

מהי האסטרטגיה הטובה ביותר לניסיונות חוזרים של משימות?

אנו ממליצים על גישה בת ארבעה שלבים:

  1. הגדר פרמטרי ניסיון חוזר.
  2. יישם את המתודה failed().
  3. הגדר תור מתים.
  4. הגדר התראות.

פרמטרי ניסיון חוזר

במחלקת Job, הגדר את מגבלת הניסיונות ואת המרווחים. backoff אקספוננציאלי פירושו שההשהיה גדלה עם כל ניסיון, ומפחיתה את העומס על שירותים חיצוניים במהלך כשלים זמניים. backoff אקספוננציאלי טוב פי 3 מ-backoff קבוע לעומס API.

class SendEmailJob implements ShouldQueue {
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public int $tries = 5; // максимум попыток
    public int $backoff = 60; // фиксированная пауза между попытками (секунды)
    public int $timeout = 30; // таймаут одной попытки

    // Экспоненциальный backoff вместо фиксированного
    public function backoff(): array {
        return [10, 30, 60, 120, 300]; // попытка 1→10с, 2→30с, 3→60с, 4→120с, 5→300с
    }
}

המתודה class SendEmailJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; public int $tries = 5; // максимум попыток public int $backoff = 60; // фиксированная пауза между попытками (секунды) public int $timeout = 30; // таймаут одной попытки // Экспоненциальный backoff вместо фиксированного public function backoff(): array { return [10, 30, 60, 120, 300]; // попытка 1→10с, 2→30с, 3→60с, 4→120с, 5→300с } } עוקפת את המאפיין backoff(). מערך מאפשר מרווחים שונים לכל ניסיון — זהו backoff אקספוננציאלי. חשוב במיוחד עבור APIs חיצוניים: אם השירות אינו זמין זמנית, אל תכה בו כל 10 שניות. backoff אקספוננציאלי מפחית את עומס ה-API פי 3 בהשוואה ל-backoff קבוע. 95% מהכשלים הזמניים מטופלים בהצלחה עם התצורה שלנו.

הבחנה בין שגיאות הניתנות לניסיון חוזר ושגיאות קטלניות

לא כל השגיאות ראויות לניסיון חוזר. פורמט נתונים לא תקין לא יתקן את עצמו בניסיון השני — זו שגיאה קטלנית. API לא זמין עשוי להגיב תוך דקה — זו שגיאה זמנית. ההבחנה חוסכת זמן ומשאבי תור. 90% מהמשימות שנכשלו נובעות משגיאות זמניות, מה שהופך סיווג נכון לקריטי.

public function handle(): void
{
    try {
        $this->processData();
    } catch (ValidationException $e) {
        // Данные невалидны — повтор бессмысленен
        $this->fail($e);
        return;
    } catch (ModelNotFoundException $e) {
        // Запись удалена — повтор не поможет
        $this->fail($e);
        return;
    } catch (ConnectionException | TimeoutException $e) {
        // Временная ошибка сети — повторяем
        throw $e; // позволяем Queue обработать retry
    } catch (\Throwable $e) {
        // Неизвестная ошибка — тоже повторяем, но логируем
        Log::warning("Unexpected error in SendEmailJob, attempt {$this->attempts()}: {$e->getMessage()}");
        throw $e;
    }
}

$backoff — מסמן מיד את ה-Job כנכשל ללא שימוש בניסיונות הנותרים. public function handle(): void { try { $this->processData(); } catch (ValidationException $e) { // Данные невалидны — повтор бессмысленен $this->fail($e); return; } catch (ModelNotFoundException $e) { // Запись удалена — повтор не поможет $this->fail($e); return; } catch (ConnectionException | TimeoutException $e) { // Временная ошибка сети — повторяем throw $e; // позволяем Queue обработать retry } catch (\Throwable $e) { // Неизвестная ошибка — тоже повторяем, но логируем Log::warning("Unexpected error in SendEmailJob, attempt {$this->attempts()}: {$e->getMessage()}"); throw $e; } } — מגדיל את מונה הניסיונות ומתזמן ניסיון חוזר.

המתודה failed() — נקודת איסוף והתראה

נקראת לאחר שכל הניסיונות מוצו. כאן אתה שומר את ההקשר, מודיע למשתמש, רושם את השגיאה ושולח התראה. יישום DLQ אמין פי 10 מאשר פשוט רישום כשלים ביומן.

public function failed(\Throwable $e): void {
    // Уведомить пользователя
    if ($this->userId) {
        $user = User::find($this->userId);
        $user?->notify(new JobFailedNotification($this->jobType, $e->getMessage()));
    }

    // Логировать с контекстом
    Log::error('Job permanently failed', [
        'job' => static::class,
        'payload' => $this->getPayloadForLog(),
        'attempts' => $this->attempts(),
        'exception' => [
            'class' => get_class($e),
            'message' => $e->getMessage(),
            'file' => $e->getFile() . ':' . $e->getLine(),
        ],
    ]);

    // Сохранить в собственную таблицу для аудита
    FailedJobAudit::create([
        'job_class' => static::class,
        'payload' => json_encode($this->getPayloadForLog()),
        'error' => $e->getMessage(),
        'failed_at' => now(),
    ]);

    // Оповестить DevOps-канал
    $this->alertSlack($e);
}

private function getPayloadForLog(): array {
    // Возвращаем только безопасные данные (без паролей, токенов)
    return ['user_id' => $this->userId, 'type' => $this->jobType];
}

יישום תור מתים ללא חבילות נוספות

תור מתים (DLQ) — תור נפרד למשימות שנכשלו לצמיתות. Laravel אינו מיישם DLQ כברירת מחדל, אך קל לבנות את התבנית באמצעות middleware.

// app/Jobs/Middleware/DeadLetterMiddleware.php
class DeadLetterMiddleware
{
    public function handle(object $job, callable $next): void
    {
        try {
            $next($job);
        } catch (\Throwable $e) {
            if ($job->attempts() >= $job->tries) {
                // Последняя попытка — отправляем в DLQ
                dispatch(new DeadLetterJob(
                    originalClass: get_class($job),
                    serializedJob: serialize($job),
                    errorMessage: $e->getMessage(),
                    errorTrace: $e->getTraceAsString(),
                ))->onQueue('dead-letter');
            }
            throw $e;
        }
    }
}

החל את ה-middleware על ה-Job: הוסף את המתודה $this->fail($e) במחלקת Job.

throw $e הוא wrapper פשוט המאחסן את המשימה הסריאלית ומאפשר לשחזר אותה מאוחר יותר. הפקודה public function failed(\Throwable $e): void { // Уведомить пользователя if ($this->userId) { $user = User::find($this->userId); $user?->notify(new JobFailedNotification($this->jobType, $e->getMessage())); } // Логировать с контекстом Log::error('Job permanently failed', [ 'job' => static::class, 'payload' => $this->getPayloadForLog(), 'attempts' => $this->attempts(), 'exception' => [ 'class' => get_class($e), 'message' => $e->getMessage(), 'file' => $e->getFile() . ':' . $e->getLine(), ], ]); // Сохранить в собственную таблицу для аудита FailedJobAudit::create([ 'job_class' => static::class, 'payload' => json_encode($this->getPayloadForLog()), 'error' => $e->getMessage(), 'failed_at' => now(), ]); // Оповестить DevOps-канал $this->alertSlack($e); } private function getPayloadForLog(): array { // Возвращаем только безопасные данные (без паролей, токенов) return ['user_id' => $this->userId, 'type' => $this->jobType]; } יכולה להפעיל מחדש משימות מה-DLQ משלושת הימים האחרונים.

הגדרת התראות כדי לא לפספס כשל

שליחת התראה ל-Slack על כשל ב-Job היא נוהג סטנדרטי. ה-wrapper // app/Jobs/Middleware/DeadLetterMiddleware.php class DeadLetterMiddleware { public function handle(object $job, callable $next): void { try { $next($job); } catch (\Throwable $e) { if ($job->attempts() >= $job->tries) { // Последняя попытка — отправляем в DLQ dispatch(new DeadLetterJob( originalClass: get_class($job), serializedJob: serialize($job), errorMessage: $e->getMessage(), errorTrace: $e->getTraceAsString(), ))->onQueue('dead-letter'); } throw $e; } } } מונע כשלים רקורסיביים אם ההתראה נכשלת בשליחה.

private function alertSlack(\Throwable $e): void {
    $env = config('app.env');
    $payload = [
        'text' => null,
        'attachments' => [[
            'color' => 'danger',
            'title' => "Job Failed [{$env}]",
            'fields' => [
                ['title' => 'Job', 'value' => static::class, 'short' => true],
                ['title' => 'Error', 'value' => $e->getMessage(), 'short' => false],
                ['title' => 'Attempts','value' => (string)$this->attempts(), 'short' => true],
                ['title' => 'Time', 'value' => now()->toDateTimeString(), 'short' => true],
            ],
            'footer' => config('app.url'),
        ]],
    ];
    rescue(fn() => Http::post(config('services.slack.job_alerts_webhook'), $payload));
}

בנוסף, ניתן להגדיר בדיקה תקופתית של מספר המשימות שנכשלו בשעה האחרונה — כאשר הסף נחצה, שלח התראה דרך Telegram.

מה כלול בהגדרת טיפול השגיאות שלנו

אנו מציעים התקנה כוללת הכוללת:

  • ביקורת של תצורת התור הנוכחית וזיהוי צווארי בקבוק
  • פיתוח אסטרטגיית ניסיון חוזר (מספר ניסיונות, backoff, timeouts)
  • יישום המתודה public function middleware(): array { return [new DeadLetterMiddleware()]; } עם רישום והתראות
  • יישום תור מתים עם middleware ופקודת שחזור
  • הגדרת התראות דרך Slack/Telegram/דוא"ל
  • תיעוד התהליך והדרכת הצוות שלך
  • כתיבת בדיקות למשימות קריטיות
  • ניטור דרך Horizon ולוחות מחוונים מותאמים אישית

מפתחי Laravel המוסמכים שלנו סיפקו 100+ הגדרות טיפול בשגיאות בתורים, ומבטיחים אמינות תורים של 99.9%.

אסטרטגיית ניסיון חוזר אופיינית לתרחישים שונים
סוג שגיאה ניסיונות Backoff פעולה במיצוי
Timeout רשת 5 [10,30,60,120,300] DLQ + התראה
שגיאת ולידציה 1 — fail() -> התראה
חוסר זמינות מסד נתונים 7 [5,15,45,135,405] DLQ + התראה

השוואת גישות: Backoff קבוע לעומת Backoff אקספוננציאלי

פרמטר Backoff קבוע Backoff אקספוננציאלי
התנהגות השהיה זהה בין ניסיונות השהיה גדלה עם כל ניסיון
עומס API גבוה — בקשות קבועות נמוך — בקשות נדירות לאחר כשלים ראשוניים
זמן התאוששות עשוי לחרוג ממגבלת המשתמש עדין לשירותים חיצוניים
המלצה למערכות פנימיות עם עלות כשל נמוכה ל-APIs חיצוניים, מסדי נתונים, שירותי צד שלישי

תור מתים (ראה ויקיפדיה) הוא תבנית סטנדרטית למערכות סובלניות לתקלות. השתמש בו כדי להימנע מאובדן נתונים במהלך כשלים.

לוחות זמנים

הגדרת אסטרטגיית ניסיון חוזר, מתודת DeadLetterJob, התראות — 3–4 שעות. יישום תור מתים עם פקודת שחזור — 4–5 שעות נוספות. אינטגרציה עם Horizon ולוח מחוונים לניטור — 2–3 שעות. מחזור מלא — החל מ-10 שעות.

קבל ייעוץ על התור שלך — ננתח את התצורה הנוכחית שלך ונציע שיפורים. הזמן הגדרת טיפול בשגיאות — והמשימות הרקע שלך יהיו עמידות לכל כשל.