Freitagabend zeigt der Laden „Bestellung bestätigt“ an. Die Bestätigungs-E-Mail wurde nie gesendet. Am Montagmorgen entdeckte der Support eine leere „Jobs“-Tabelle auf der Anwendungsseite – aber Hunderte von Einträgen in „failed_jobs“, die alle mit einem SMTP-Timeout nach dem Versions-Upgrade am Wochenende verknüpft waren.
Dieses Szenario ist banal: Die Webschnittstelle reagiert schnell, weil Laravel den Job erfolgreich verteilt hat, aber niemand den Verbrauch oder die Fehler überwacht hat. Wenn alles gut läuft, sind Warteschlangen kein Problem. Sie werden sichtbar, wenn ein Worker stoppt, ein schlecht konfigurierter Treiber auf „Sync“ wechselt oder ein aggressiver Wiederholungsversuch einen externen Fehler verstärkt.
Treiber, Verbindung und was Laravel wirklich ausführt
Ein Laravel-Job ist keine Zauberei: Es handelt sich um eine serialisierte Nachricht (Klasse, Nutzlast, Versuche), die in einem Backend gespeichert wird – Redis, Datenbank, SQS, Beanstalkd. Der Worker („queue:work“ oder Horizon) öffnet es, instanziiert die Klasse, führt „handle()“ aus und bestätigt oder markiert dann den Fehler.
| Fahrer | Wann sollte man es verwenden | Häufiges Limit |
|---|---|---|
redis | Produktion mit mehreren Mitarbeitern, geringe Latenz | Redis muss persistent sein und überwacht werden |
Datenbank | Kleines Volumen, kein Makler | Konflikt in der Tabelle „Jobs“ mit hoher Auslastung |
sqs | AWS Cloud, regionale Entkopplung | Kosten und Sichtbarkeit der zu konfigurierenden DLQs |
sync | Nur lokale Tests | Inline-Ausführung – keine Ausfallsicherheit |
Bei Shared Hosting, verwaltetem Redis oder einem kleinen VPS, der dem Broker gewidmet ist, wird eine Vermischung von Weblast und Auftragsverbrauch vermieden. Dokumentieren Sie auf einem einzelnen VPS, wer den Worker nach einer Bereitstellung neu startet: Ein schlecht neu geladener „Supervisor“ lässt die Warteschlange wachsen, ohne dass auf der HTTP-Seite ein Fehler sichtbar ist.
Eine Site, die innerhalb von 200 ms antwortet, kann funktionsunfähig sein, wenn ihre Mitarbeiter seit dem Tag zuvor angehalten wurden.
Wiederholungsversuche, Backoffs und idempotente Jobs
Laravel wiederholt automatisch Jobs, die eine Ausnahme auslösen, abhängig von „$tries“, „$backoff“ oder „$retryUntil“. Dies ist nützlich für eine Drittanbieter-API, die vorübergehend nicht verfügbar ist. Dies ist gefährlich für einen Job, der Geld sendet, eine Rechnung erstellt oder einen nicht idempotenten Webhook aufruft.
Pragmatische Regeln:
- Exponentielles Backoff anstelle von zehn Versuchen in zehn Sekunden bei demselben Strukturfehler.
$maxExceptionsum einen fehlerhaften Job zu stoppen, bevor die Warteschlange erschöpft ist.- Idempotenz: Ein zweiter Durchgang darf den Effekt nicht verdoppeln (eindeutiger Schlüssel in der Basis, Redis-Sperre, Status „bereits verarbeitet“).
„ShouldBeUnique“-Jobs und ratenbegrenzende Middleware vermeiden auch Stürme, wenn hunderttausend Befehle die gleiche Verarbeitung auslösen.
Fehlgeschlagene Jobs, Horizon und wichtige Warnungen
Die Tabelle „failed_jobs“ (oder der Horizon-Bildschirm) ist Ihre Fehlerwarteschlange. Viele Teams aktivieren es während der Migration und konsultieren es dann nie.
Einrichten:
- Warnung, wenn „failed_jobs“ > 0 in kritischen Warteschlangen („Zahlungen“, „Benachrichtigungen“).
- Dashboard Horizon oder Prometheus-Metrik für „queue_size“, „jobs_processed“, „failed_jobs_total“.
- Prozedur: die neu startet („queue:retry all“), die nach der Korrektur löscht, die den Vorfall verfolgt.
Horizon zentralisiert die Redis-Überwachung: Wartezeit, Durchsatz, aktive Mitarbeiter. Ohne Horizon erkennt ein Cron-Skript, das das Alter des ältesten Jobs in Redis („LLEN“, „LRANGE“) überprüft, bereits einen toten Worker.
Einsatz, Vorgesetzter und die Zombie-Arbeiter-Falle
Eine Bereitstellung, die den Code ersetzt, ohne die Worker neu zu starten, führt manchmal stundenlang die alte Version von Jobs aus. Laravel dokumentiert „queue:restart“, um ein ordnungsgemäßes Neuladen zu signalisieren.
Checkliste für die Bereitstellung:
php artisan queue:restartnach der Aktualisierung des Codes.- Supervisor (oder systemd) mit „autorestart=true“.
- Trennen Sie schwere Warteschlangen („--queue=default,emails“), um dringende Jobs nicht zu blockieren.
Auf Docker Compose oder Kubernetes ist ein Worker nicht „nur ein weiterer Container“: Er muss dieselbe Image-Version wie die App, dieselben Umgebungsvariablen und eine Gesundheitsprüfung haben, die überprüft, ob er ordnungsgemäß konsumiert – und nicht nur, dass er ausgeführt wird.
Der Gipfel: Die Warteschlange verbirgt einen geschäftlichen Misserfolg
Folgendes wird in den Tutorials „Laravel-Warteschlangen in 5 Minuten“ weggelassen.
Der Schwanz ist ein aufgeschobenes Versprechen. Ohne Beobachtbarkeit und ohne eine Kultur der „failed_jobs“ lagern Sie das Problem an den Kundensupport oder an einen Partner aus, der Ihren Rückruf nie erhalten wird.
Entscheide dich und gehe ohne blinden Fleck voran
Ordnen Sie Ihre Aufgaben zu: welche kritisch sind, welche Verzögerungen tolerieren, welche idempotent sein müssen. Wählen Sie einen an Ihr Hosting angepassten Treiber (Redis auf VPS, SQS in der Cloud). Konfigurieren Sie Wiederholungsversuche mit Backoff, Fehlerwarnungen und „queue:restart“ in Ihrer Bereitstellungspipeline.
Um Angebote mit verwalteten Redis, dedizierten Mitarbeitern oder Überwachung zu vergleichen, durchsuchen Sie unser Verzeichnis und den Vergleicher. Die Anleitungen und Artikel nach Nutzung helfen dabei, die Infrastruktur rund um Ihren PHP-Stack zu dimensionieren.
Konkreter Test: Töten Sie einen Arbeiter im Staging, versenden Sie zehn Jobs, überprüfen Sie die Warnung und den Inhalt von „failed_jobs“. Wenn innerhalb von fünfzehn Minuten niemand benachrichtigt wird, ist die Warteschlange noch nicht betriebsbereit.
Häufig gestellte Fragen
Welchen Hecktreiber soll ich bei Laravel wählen?
Redis oder SQS für die Produktion mit mehreren Arbeitern; „Datenbank“ ist für kleine Volumina geeignet. Der „Sync“-Treiber darf niemals in der Produktion bleiben: Er verbirgt Parallelität und Zeitüberschreitungen.
Was tun mit Jobs, die nach allen Wiederholungsversuchen fehlschlagen?
Sie landen in „failed_jobs“. Alarmieren, analysieren, beheben und dann mit „queue:retry“ erneut versuchen oder nach Ablaufverfolgung löschen – lassen Sie nicht zu, dass sich diese häufen.
Sollte Horizon auf einem kleinen VPS laufen?
Sobald mehrere Mitarbeiter oder kritische Jobs ins Spiel kommen, vereinfacht Horizon die Überwachung. Bei einem einzelnen Prozess können zunächst ein Gesundheits-Cron und Warnungen zu „failed_jobs“ ausreichend sein.
Wie bemisst man die Anzahl der Arbeiter?
Trennen Sie Warteschlangen nach Lasttyp und messen Sie den langsamsten Job. Durch die Vervielfachung von Mitarbeitern in einer durch externe Anrufe blockierten Warteschlange entstehen nur mehr parallele Verbindungen, nicht jedoch ein höherer nutzbarer Durchsatz.
Wenn eine Bereitstellung das nächste Mal „erfolgreich“ ist, überprüfen Sie eines: Verarbeitet noch ein Mitarbeiter die Warteschlange – und tauchen die Fehler irgendwo auf?
