Zum Inhalt springen
DedicatedPHP Kontakt

Warteschlangen für langsame Vorgänge in PHP entwerfen

Erfahre, wann ein Vorgang außerhalb der Webanfrage ausgeführt werden sollte und wie sich Status, Fortschritt, Ergebnisse, Abbruch und Fehler sicher verwalten lassen.

Konzeptionelles Diagramm des Lebenszyklus einer PHP-Aufgabe: ausstehend, in Bearbeitung, abgeschlossen, fehlgeschlagen oder abgebrochen

Ein Vorgang, der mehrere Sekunden dauert, kann eine HTTP-Anfrage offen halten, Ressourcen des Webservers verbrauchen und für eine ungewisse Nutzererfahrung sorgen, wenn die Verbindung unterbrochen wird. Hintergrundprozesse in PHP ermöglichen es, einen Auftrag anzunehmen und außerhalb des Lebenszyklus dieser Anfrage auszuführen. Damit die Lösung sinnvoll ist, reicht es nicht, einfach eine Warteschlange hinzuzufügen: Es muss festgelegt werden, was der Nutzer erhält, wie er den Status abfragen kann und was bei einer Unterbrechung geschieht.

Erkennen, welche Vorgänge im Hintergrund ausgeführt werden sollten

Erkennen, welche Vorgänge im Hintergrund ausgeführt werden sollten — guía visual de DedicatedPHP

Es empfiehlt sich, die Auswirkungen eines Vorgangs zu bewerten, statt eine Regel anzuwenden, die sich ausschließlich an seiner Dauer orientiert. Eine Aufgabe kommt infrage, wenn ihre Laufzeit variiert, sie auf ein externes System warten muss oder viele Elemente verarbeitet. Beispiele dafür sind das Erstellen eines umfangreichen Berichts, der Import einer Datei, die Umwandlung von Dokumenten oder die Synchronisierung von Daten mit einer API.

Benötigt der Nutzer hingegen eine sofortige Entscheidung, um fortzufahren – etwa die Validierung einer wesentlichen Angabe vor dem Speichern –, kann es besser sein, diesen Teil in der Anfrage zu belassen und nur die anschließende Arbeit auszulagern. Auch langsame Aufgaben können aus geschäftlichen Gründen eine synchrone Antwort erfordern. Die Architektur sollte sich nach den Anforderungen des Ablaufs richten und nicht jeden Vorgang in einen asynchronen Auftrag verwandeln.

Ermittle vor einer Änderung des Designs, wie lange der Vorgang dauert, welcher Teil dafür verantwortlich ist und was bei einem Fehler geschieht. Eine Warteschlange behebt weder ineffiziente Abfragen noch falsch konfigurierte Grenzwerte oder instabile externe Abhängigkeiten von selbst; sie kann diese Probleme lediglich auf die Hintergrund-Worker verlagern.

Mit einer angenommenen Aufgabe antworten, nicht mit einem erfundenen Ergebnis

Wird ein Auftrag zur späteren Ausführung angenommen, muss die Antwort der Anwendung klar zwischen angenommen und abgeschlossen unterscheiden. Sie kann eine Aufgaben-ID und einen Hinweis zurückgeben, dass die Verarbeitung noch aussteht. Ein Ergebnis, das noch nicht vorliegt, darf nicht als abgeschlossen dargestellt werden.

Eine Dauerprognose ist nur dann angemessen, wenn genügend Informationen vorliegen, um sie zu berechnen und ihre Unsicherheit zu vermitteln. In vielen Systemen ist es ehrlicher, einen Status wie „in der Warteschlange“ oder „in Bearbeitung“ anzuzeigen, als eine Abschlusszeit zu versprechen. Kann die Aufgabe schnell abgeschlossen werden, kann die Benutzeroberfläche den Status trotzdem abfragen und das Ergebnis anzeigen, sobald es verfügbar ist, ohne die ursprüngliche Anfrage zu blockieren.

Lege auch fest, was geschieht, wenn das Einstellen in die Warteschlange fehlschlägt: Die Anwendung darf die Annahme nicht bestätigen, wenn sie den Auftrag nicht zuverlässig registrieren kann. Der konkrete Mechanismus hängt von der Architektur ab, doch die Antwort und der gespeicherte Status müssen konsistent sein.

Gültige Status und Übergänge festlegen

Ein kleiner, expliziter Lebenszyklus erleichtert die Nutzererfahrung und den Betrieb. Als Grundlage eignen sich ausstehend, in_bearbeitung, abbruch_angefordert, abgeschlossen, fehlgeschlagen und abgebrochen. Die Bezeichnungen können variieren; die Übergänge hingegen müssen gültig und überprüfbar sein und dürfen keine beliebige Kombination von Status darstellen.

  • Normale Übergänge: ausstehend → in_bearbeitung und von in_bearbeitung zu abgeschlossen oder fehlgeschlagen.
  • Abbruch vor dem Start: ausstehend → abgebrochen, wenn bestätigt ist, dass der Worker noch nicht mit der Arbeit begonnen hat.
  • Abbruch während der Ausführung: in_bearbeitung → abbruch_angefordert. Von diesem Status wechselt die Aufgabe zu abgebrochen, wenn sie sicher angehalten wird; sie kann zu abgeschlossen wechseln, wenn sie vor der Bearbeitung der Anforderung beendet wurde, oder zu fehlgeschlagen, wenn ein Fehler aufgetreten ist.
  • Endstatus: abgeschlossen, fehlgeschlagen und abgebrochen sollten nicht wieder in aktive Status übergehen. Ist eine Wiederholung einer Aufgabe zulässig, erstelle eine neue Ausführung oder definiere ausdrücklich einen anderen Ablauf.

Das System muss unzulässige Übergänge verhindern und erfassen, wann jede Änderung erfolgt ist. Wird ein Worker unterbrochen und bleibt eine Aufgabe im Status in_bearbeitung, darf sie nicht automatisch als abgeschlossen markiert werden. Eine Wiederherstellungsrichtlinie kann sie zu ausstehend zurücksetzen, wenn eine sichere Fortsetzung möglich ist, oder sie zur Überprüfung als fehlgeschlagen markieren. Die Entscheidung hängt davon ab, ob die Arbeit ohne doppelte Auswirkungen fortgesetzt werden kann. Der Umgang mit Wiederholungsversuchen und Idempotenz erfordert eigene Entscheidungen und darf nicht mit dem sichtbaren Statusmodell verwechselt werden.

Fortschritt, Ergebnisse und Fehler kommunizieren

Der Fortschritt sollte auf messbaren Meilensteinen beruhen. Lässt sich kein tatsächlicher Prozentwert berechnen, ist es besser, die Phase („Daten werden validiert“, „Bericht wird erstellt“) anzugeben oder den Status „in Bearbeitung“ beizubehalten. Ein Prozentwert, der unverändert bleibt oder sich ohne Erklärung verringert, untergräbt das Vertrauen.

Stelle nach dem Abschluss das fachliche Ergebnis bereit, zum Beispiel eine Zusammenfassung der verarbeiteten Elemente oder einen Verweis auf die erstellte Ressource, jeweils vorbehaltlich der Berechtigungen und Verfügbarkeit. Der Aufgabenstatus muss nicht das gesamte Ergebnis enthalten. Er kann auf Daten verweisen, die von der Anwendungsdomäne verwaltet werden.

Zeige bei einem Fehler eine Meldung an, die bei der Entscheidung über den nächsten Schritt hilft, etwa eine Datei zu korrigieren oder es gegebenenfalls erneut zu versuchen. Speichere die für die Diagnose erforderlichen technischen Fehlerinformationen getrennt und beschränke den Zugriff darauf. Gib weder Stacktraces noch Zugangsdaten, interne Pfade oder sensible Daten in der Benutzeroberfläche oder einer öffentlichen API preis.

Abbruch als Anforderung mit Einschränkungen behandeln

Eine Aufgabe abzubrechen bedeutet nicht immer, dass sie sofort angehalten werden kann. Ein Worker kann gerade einen externen Aufruf ausführen, Daten schreiben oder sich in einer Phase befinden, die keine sichere Unterbrechung zulässt. Deshalb muss die Benutzeroberfläche zwischen abbruch_angefordert und abgebrochen unterscheiden: Der erste Status zeigt an, dass die Anforderung eingegangen ist; der zweite, dass das System den Abbruch bestätigt hat.

Die Implementierung kann an sicheren Punkten ein Abbruchsignal prüfen und davon absehen, weitere Schritte zu starten. Wurde eine Auswirkung bereits in einem externen System bestätigt, darf nicht behauptet werden, sie sei rückgängig gemacht worden. Erkläre dem Nutzer, welches Ergebnis zu erwarten ist, und protokolliere, wer den Abbruch angefordert hat, sofern diese Information für Prüfzwecke relevant ist.

Aufgabenregistrierung und fachliches Ergebnis trennen

Die Aufgabenregistrierung dient der Koordination von Ausführung und Abfrage. Sie kann eine ID, den Status, Zeitangaben, den Anforderer und Verweise für die Diagnose enthalten. Das fachliche Ergebnis – beispielsweise ein Bericht oder die importierten Datensätze – gehört zum Datenmodell, das dieses Ergebnis repräsentiert.

Durch die Trennung wird verhindert, dass eine Aufgabe mit temporären Informationen zur einzigen Quelle für den fachlichen Bereich wird. Außerdem lässt sich so die Aufbewahrung festlegen: wie lange der Status gespeichert bleibt, wann eine Datei gelöscht wird und welche Informationen aufgrund betrieblicher oder gesetzlicher Pflichten aufbewahrt werden müssen. Alte Status sollten sich nicht ohne Bereinigungsrichtlinie ansammeln.

Abfragen schützen und Ressourcenverbrauch begrenzen

Für die Abfrage einer Aufgabe ist ebenso eine Berechtigung erforderlich wie für die Abfrage jeder anderen Ressource. Die ID ersetzt keine Zugriffskontrolle: Prüfe, ob die anfragende Person oder das System diese Aufgabe und ihr Ergebnis sehen darf. Begrenze außerdem Häufigkeit und Umfang der Abfragen, um übermäßiges Polling zu vermeiden, und ziehe Benachrichtigungen in Betracht, wenn der Anwendungsfall keine ständigen Aktualisierungen erfordert.

Die Ausführung benötigt Parallelitäts- und Ressourcengrenzen, die zur Art der Arbeit passen. Zu viele Worker können Datenbank, externe Dienste oder Speicher überlasten; zu wenige können Aufgaben auflaufen lassen und Ergebnisse verzögern. Beobachte neben Fehlern auch das ausstehende Volumen, das Alter der Aufgaben und ihre Laufzeiten. Diese Signale helfen dabei, eine langsame Abhängigkeit von einem Kapazitätsproblem zu unterscheiden.

Den vollständigen Ablauf vor der Bereitstellung testen

Abnahmetests sollten das sichtbare Verhalten und die Persistenz abdecken, nicht nur prüfen, ob der Worker eine Funktion aufruft. Überprüfe mindestens die folgenden Szenarien:

  • Die Anfrage erstellt eine Aufgabe und gibt eine Referenz zurück, ohne zu behaupten, dass die Aufgabe bereits abgeschlossen ist.
  • Bei einer abgeschlossenen Aufgabe wird der Endstatus angezeigt, und mit den richtigen Berechtigungen ist der Zugriff auf das Ergebnis möglich.
  • Eine fehlgeschlagene Aufgabe vermittelt eine sichere Meldung und stellt dem autorisierten Team Diagnoseinformationen zur Verfügung.
  • Eine verlassene oder unterbrochene Aufgabe bleibt nicht unbegrenzt „in Bearbeitung“; es gibt eine betriebliche Möglichkeit, sie zu erkennen und zu behandeln.
  • Eine Abbruchanforderung berücksichtigt sichere Phasen und verspricht nicht, bereits eingetretene Auswirkungen rückgängig zu machen.

Führe die Änderung in einem bestehenden System für einen klar abgegrenzten Vorgang ein und überprüfe auch die Nutzererfahrung, wenn die Warteschlange verzögert oder nicht verfügbar ist. Die Anwendung benötigt für solche Fälle eine klare Antwort: mitteilen, dass der Auftrag nicht angenommen werden konnte, eine sichere Alternative anbieten oder dem Nutzer einen erneuten Versuch ermöglichen. Die Entscheidung hängt von den Auswirkungen des Vorgangs und den Garantien ab, die das Unternehmen tatsächlich einhalten kann.

Checkliste für die Einführung einer Warteschlange in ein bestehendes System

Checkliste für die Einführung einer Warteschlange in ein bestehendes System — guía visual de DedicatedPHP

Prüfe vor der Aktivierung der Hintergrundverarbeitung die folgenden Punkte gemeinsam mit den für die Anwendung und ihren Betrieb verantwortlichen Teams:

  • Umfang: Ein konkreter Vorgang wurde ausgewählt und es ist festgelegt, welcher Teil synchron bleibt und welche Arbeit im Hintergrund ausgeführt wird.
  • Persistenz: Die Annahme der Aufgabe und ihr Status werden konsistent gespeichert; eine Richtlinie für Unterbrechungen, Wiederherstellung und Statusänderungen ist vorhanden.
  • Vereinbarung mit dem Nutzer: Die erste Antwort unterscheidet zwischen Annahme und Abschluss, und die Benutzeroberfläche erklärt, wie Fortschritt, Ergebnis und Fehler abgefragt werden können.
  • Berechtigungen und Daten: Für die Abfrage einer Aufgabe oder ihres Ergebnisses ist eine Berechtigung erforderlich; gespeicherte Daten werden minimiert und der Zugriff auf Diagnoseinformationen eingeschränkt.
  • Ressourcen: Für den Vorgang und seine Abhängigkeiten wurden angemessene Grenzen für Parallelität, Ausführungszeit, Arbeitsspeicher und Abfragehäufigkeit festgelegt.
  • Beobachtbarkeit: Auflaufende Aufgaben, alte Aufgaben im Status „in Bearbeitung“, Fehler und ungewöhnliche Laufzeiten lassen sich erkennen, ohne Geheimnisse in Protokolle aufzunehmen.
  • Aufbewahrung: Es wurde festgelegt, wie lange Status, Ergebnisse, Dateien und Diagnoseinformationen aufbewahrt und wie sie kontrolliert gelöscht werden.
  • Tests und Betrieb: Die Abläufe für Abschluss, Fehler, Abbruch und Unterbrechung wurden getestet, und das Team weiß, was zu tun ist, wenn die Warteschlange keine Aufträge annimmt oder sich verzögert.

Die Bereitstellung des Codes bedeutet nicht, dass sofort alle Abläufe aktiviert werden müssen: Du kannst den neuen Ausführungspfad schrittweise einführen und seine Kennzahlen prüfen, bevor du ihn ausweitest. Halte eine geeignete betriebliche Alternative bereit, falls die Warteschlange oder ihre Worker nicht verfügbar sind; bestätige keine Aufträge, die das System nicht registrieren konnte.

Möchten Sie diese Ideen in Ihrem Projekt anwenden?Lass uns über deine PHP-Plattform sprechen.
Verwandten Dienst anzeigen