Laravel 13.31 führt unterbrechbare Jobs ein, die es Queue-Workern ermöglichen, das während Deployments gesendete SIGTERM-Signal abzufangen und sauber herunterzufahren, anstatt eine Aufgabe mitten im Prozess abzubrechen. Teams, die langlaufende Jobs ausführen – wie die Verarbeitung von zehntausenden Zeilen, das Versenden von Massen-E-Mails oder das Erstellen von Berichten – profitieren davon, da die Daten konsistent bleiben, wenn ein neues Release ausgerollt wird.

Warum Deployments bisher Jobs unterbrochen haben

Wenn eine neue Version bereitgestellt wird, weisen Prozess-Manager wie Supervisor, Docker und Kubernetes die bestehenden Worker durch das Senden von SIGTERM an, eine höfliche Aufforderung zum Beenden. Die meisten Worker warten, bis der aktuelle Job abgeschlossen ist, bevor sie sich beenden. Das Problem entsteht, wenn der Manager nur wenige Sekunden für die Einhaltung gewährt. Wenn ein Job Minuten benötigt, eskaliert der Manager zu SIGKILL, was den Prozess sofort beendet. Der Job erreicht nie einen konsistenten Zustand, was zu teilweise aktualisierten Datensätzen, verwaisten Dateien oder doppelter Arbeit führt.

Laravel’s Antwort: kooperative Unterbrechung

Laravel 13.31 führt einen Contract namens Interruptible ein, den eine Job-Klasse implementieren kann, um auf die Beendigungsaufforderung reagieren zu können. Wenn SIGTERM eintrifft, ruft Laravel die interrupted()-Methode des Jobs auf. Das Framework stoppt den Job nicht automatisch; der Job muss selbst ein Flag prüfen, das Laravel setzt, und sich eigenständig beenden. Dieses kooperative Modell ermöglicht es Entwicklern, die aktuelle Schleifeniteration abzuschließen, Teiländerungen zurückzurollen oder einen Checkpoint zu schreiben, bevor sie beendet werden.

So machen Sie einen Job unterbrechbar

  1. Implementieren Sie den Contract – fügen Sie implements Interruptible zur Definition der Job-Klasse hinzu.
  2. Prüfen Sie das Flag innerhalb der Work-Loop – fügen Sie in jeder Iteration eine Prüfung ein, um zu sehen, ob der Job stoppen sollte.
  3. Führen Sie Aufräumarbeiten durch – speichern Sie in interrupted() jeden Zustand, der es dem Job ermöglicht, später fortzufahren, oder protokollieren Sie die Unterbrechung für eine spätere Analyse.

Die größte Falle: Verwenden Sie nicht --once

Das Ausführen des Queue-Workers mit php artisan queue:work --once deaktiviert das Signal-Handling vollständig. Der Worker verarbeitet einen einzelnen Job und beendet sich, registriert aber nie den SIGTERM-Handler. Infolgedessen ignoriert jeder unterbrechbare Job die Beendigungsaufforderung und wird mitten im Prozess getötet. Dieses Muster tritt in Cron-gesteuerten Containern und One-Shot-Deployments auf. Beheben Sie dies, indem Sie den Daemon-Modus (php artisan queue:work) verwenden, wann immer Sie unterbrechbare Jobs benötigen.

Überwachung von Unterbrechungen

Laravel feuert zwei Events, an die Sie sich hängen können:

  • WorkerInterrupted – wird ausgelöst, wann immer ein Worker ein SIGTERM erhält. Das Protokollieren dieses Events gibt eine Gesamtübersicht darüber, wie oft Deployments Worker unterbrechen.
  • JobInterrupted – wird nur ausgelöst, wenn der aktuelle Job den Interruptible-Contract implementiert. Nutzen Sie dieses Event, um jobspezifische Aufräumarbeiten auszuführen, wie das Löschen temporärer Dateien oder das Aktualisieren eines „zuletzt verarbeiteten Zeile“-Markers.

Das Abonnieren dieser Events ermöglicht es Teams, Dashboards zu erstellen, die die Auswirkungen von Deployments aufzeigen und Jobs identifizieren, die häufig vorzeitig abgebrochen werden.

Berichterstattung zur Warteschlangengröße erhält ein Update

Das Release fügt dem Queue-Manager eine totalSize()-Methode hinzu, die die Gesamtzahl der ausstehenden Jobs über alle Queues hinweg zurückgibt. Der Wert ist für Datenbank-basierte und Redis-Treiber zuverlässig, da diese die tatsächlichen Zahlen melden. Treiber wie SQS, Sync und Beanstalkd geben weiterhin Null zurück, da sie keine Anzahl über die Laravel-API offenlegen. Teams, die SQS nutzen, sollten weiterhin auf CloudWatch-Metriken für die Warteschlangentiefe vertrauen.

Was dies für verschiedene Setups bedeutet

  • Docker/Kubernetes – der Graceful-Shutdown-Zeitraum kann nun effektiv genutzt werden. Verlängern Sie die Zeitspanne für die Beendigung, damit Jobs einige Sekunden Zeit haben, das Flag zu bemerken und sauber herunterzufahren.
  • Supervisor – setzen Sie stopwaitsecs höher als die Zeit, die ein Job nach Erhalt des Unterbrechungs-Flags voraussichtlich zum Abschluss benötigt.
  • Legacy-Jobs – überprüfen Sie alle Jobs, die länger laufen als das Timeout des Managers, und machen Sie diese, wo möglich, unterbrechbar.

Gegenargument: erhöhte Komplexität

Das Feature ersetzt keine korrekte Timeout-Konfiguration. Wenn die Schleife eines Jobs das Unterbrechungs-Flag nie prüft, wird der Manager dennoch SIGKILL senden. Teams müssen langlaufende Code-Pfade prüfen und an logischen Breakpoints Checks einfügen. Einige Entwickler könnten den zusätzlichen Boilerplate-Code – die Implementierung eines Contracts und das Hinzufügen von Flag-Prüfungen – für kurze Jobs, die ohnehin innerhalb des Shutdown-Fensters fertig werden, als unvorteilhaft empfinden.

Checkliste

  1. Scannen Sie Deployment-Skripte nach dem --once-Flag und ersetzen Sie es durch den Daemon-Modus, sofern unterbrechbare Jobs verwendet werden.
  2. Identifizieren Sie die am längsten laufenden Jobs (jene, die zehntausende Zeilen verarbeiten oder mehrere Minuten laufen) und fügen Sie das Interruptible-Contract hinzu.
  3. Fügen Sie innerhalb jeder Schleifeniteration eine Flag-Prüfung ein und verschieben Sie den notwendigen Finalisierungscode in die interrupted()-Methode.
  4. Binden Sie Listener an WorkerInterrupted und JobInterrupted an, um Metriken darüber zu sammeln, wie häufig Deployments die Verarbeitung beeinflussen.
  5. Verwenden Sie für Redis- oder Datenbank-Queues totalSize(), um den Rückstau zu überwachen; behalten Sie bei SQS die CloudWatch-Alarme bei.

Betrachten Sie durch Deployments verursachte Abschaltungen als einen koordinierten Schritt statt als ein abruptes Beenden. Laravel 13.31 gewährleistet die Datenkonsistenz und verringert den operativen Aufwand durch halbfertige Jobs. Der Kompromiss ist eine geringfügig höhere Verantwortung im Code, aber Teams, die auf intensive Hintergrundverarbeitung angewiesen sind, gewinnen eine zuverlässigere Produktionsumgebung.