Ein Symfony E-Commerce versendet die PDF-Rechnung per Messenger, sobald eine Bestellung bezahlt ist. Der AMQP-Transport ist konfiguriert, die Worker laufen – außer dass der PDF-Generierungsdienst zwanzig Minuten lang einen 503-Fehler zurückgibt. Bei automatischen Wiederholungsversuchen wird dieselbe Nachricht vierzig Mal wiederholt. Ergebnis: 40 E-Mails an den Kunden und eine überfüllte Warteschlange, die die wahren Vorfälle verbirgt.
Messenger ist nicht nur ein „Zauberbus“. Es handelt sich um einen Vertrag zwischen dem Moment, in dem Sie eine Nachricht versenden, und dem Moment, in dem ein Handler sie ausführt – mit Transportoptionen, Wiederholungsrichtlinien, Middleware und Transportfehlern. Jede Option verändert die Belastbarkeit und das Risiko einer Duplizierung.
Transporte: sync, Doctrine, Redis, AMQP
Symfony leitet Nachrichten über in „messenger.yaml“ konfigurierte Transporte weiter. Das Routing („App\Message\* -> async“) bestimmt, wohin jede Klasse geht.
| Transport | Anwendungsfälle | Punkt der Wachsamkeit |
|---|---|---|
| synchronisieren | Entwicklung, ultraschnelle Handler | Maskierungslatenz und Timeouts in der Produktion |
| Lehre://Standard | Kleines Volumen, kein Redis | Tabelle „messenger_messages“, Basissperren |
| redis:// | Leichte Linien, geringe Ausbeutung | Redis-Persistenz, Nachrichten-TTL |
| amqp:// (RabbitMQ) | Mehrarbeiterproduktion, DLX | Topologieaustausche und zu dokumentierende Dateien |
Auf einem einzigen VPS kann Doctrine für Hunderte von Nachrichten pro Stunde ausreichen. Sobald die Handler externe APIs aufrufen oder länger als ein paar Sekunden dauern, vermeidet ein dedizierter Broker das Blockieren von Webanfragen und vereinfacht die horizontale Skalierung von „messenger:consume“-Workern.
Wenn Sie sich für den Transport entscheiden, entscheiden Sie, wer die Liefergarantie trägt – und nicht nur, wo das JSON gespeichert werden soll.
Wiederholungsversuche, Verzögerungen und vorübergehende im Vergleich zu permanenten Fehlern
Die RetryStrategy-Komponente („max_retries“, „delay“, „multiplier“) versucht fehlgeschlagene Nachrichten erneut. Ohne zwischen „API nicht verfügbar“ und „ungültige Nutzlast“ zu unterscheiden, verstärken Sie einen Codefehler.
Wenden Sie bei Netzwerkfehlern wenige Wiederholungsversuche (drei bis fünf) mit exponentiellem Backoff an. Lösen Sie „UnrecoverableMessageHandlingException“ für definitive Geschäftsfehler aus. Legen Sie ein Handler-Timeout fest: Ein Handler, der unbegrenzt auf einen Dritten wartet, blockiert einen gesamten Worker.
Test im Staging: Fahren Sie den Zieldienst absichtlich herunter und beobachten Sie das Verhalten der Warteschlange – nicht nur das Handler-Protokoll.
Fehlertransport und kontrollierte Wiedergabe
Nach Ausschöpfung der Wiederholungsversuche kann Messenger zu einem Fehlertransport („failed://“, dedizierte Warteschlange oder Doctrine-Tabelle) weiterleiten. Dies ist Ihre Quarantänezone.
Warnung, wenn der Fehlertransport nicht leer ist. Verwenden Sie „messenger:failed:show“ und „messenger:failed:retry“ für die Wiedergabe nach dem Fix. Definieren Sie eine Aufbewahrungsrichtlinie: Bewahren Sie tote Nachrichten nicht sechs Monate lang ohne Analyse auf.
Ohne Fehlertransport können je nach Konfiguration Nachrichten gelöscht werden oder einen Worker in einer Schleife blockieren – zwei verschiedene Arten, die Sichtbarkeit zu „verlieren“.
Arbeiter, Überwachung und Bereitstellungskonsistenz
„messenger:consume async -vv --time-limit=3600 --memory-limit=128M“-Worker sollten wie Produktionsdienste überwacht werden. Nach der Bereitstellung starten Sie die Worker neu (Signal oder „--stop-when-empty“ und dann neu starten). Stellen Sie sicher, dass dieselbe Codeversion und dieselben Umgebungsvariablen wie bei PHP-FPM verwendet werden. Legen Sie Speichergrenzen und Zeitlimits fest, um langsame Lecks zu vermeiden.
Auf Kubernetes vermeidet eine separate Bereitstellung für Verbraucher die Skalierung von Web-Pods, wenn nur die Warteschlange wächst. Durch die automatische Skalierung der Dateilänge (KEDA, Prometheus) wird die richtige Komponente skaliert – nicht die HTTP-Front.
Middleware, Routing und vergessene synchrone Handler
Stellen Sie sicher, dass jede kritische Geschäftsnachricht „asynchron“ durchlaufen wird. Ein schwerer Handler, der synchron bleibt, führt zu Nginx-Timeouts und zeitweiligen 502-Fehlern, die schwer zu reproduzieren sind.
Die Middleware „DoctrinePingConnectionMiddleware“ und „DoctrineCloseConnectionMiddleware“ vermeiden veraltete MySQL-Verbindungen bei lang laufenden Workern – ein Klassiker bei Shared Hosting oder einer verwalteten Datenbank mit aggressivem Timeout.
Der Gipfel: Transport garantiert keine Geschäftssemantik
Die Frage lautet also nicht „Redis oder RabbitMQ?“ " Erste. Es lautet: Was passiert, wenn dieser Handler zweimal ausgeführt wird? Solange die Antwort unklar ist, ist der Transport nur ein Infrastrukturdetail.
Entscheide dich und gehe ohne blinden Fleck voran
Listen Sie Ihre Nachrichten mit akzeptabler Latenz, Kritikalität und Idempotenz auf. Wählen Sie Transport und Fehlertransport entsprechend aus. Konfigurieren Sie Wiederholungsversuche mit Backoff, überwachen Sie Worker und testen Sie den Ausfall des Downstream-Dienstes im Staging vor der Produktion.
Um die Größe von Redis, RabbitMQ oder Workern auf europäischen VPS und Cloud zu ermitteln, konsultieren Sie das Verzeichnis und den Vergleicher. Die Anleitungen vervollständigen das PHP-Infrastruktur-Framework. Nützliche Übung: Simulieren Sie eine permanente Ausnahme – die Nachricht sollte im Fehlertransport landen, ohne die gesamte Warteschlange zu blockieren.
Häufig gestellte Fragen
Was ist der Unterschied zwischen synchron und asynchron im Messenger?
Der Sync-Transport führt den Handler sofort in der HTTP-Anfrage aus – praktisch in der Entwicklung, gefährlich in der Produktion für langsame Aufgaben. Async sendet die Nachricht an eine Warteschlange, die von separaten Workern genutzt wird.
Transportdoktrin oder Redis/AMQP?
Doctrine eignet sich für kleine Projekte ohne dedizierten Broker, die Nachrichtentabelle wird jedoch zum Engpass. Redis oder AMQP skalieren besser, wenn Volumen, Latenz oder Parallelität zunehmen.
Wofür wird der Fehlertransport verwendet?
Es isoliert fehlgeschlagene Nachrichten nach Ablauf der Wiederholungsversuche zur Überprüfung und manuellen Wiedergabe. Ohne konfigurierten Fehlertransport können Nachrichten verschwinden oder den Verbrauch blockieren.
Wie vermeide ich Duplikate bei Wiederholungsversuchen?
Machen Sie Handler idempotent (Sperre, Basisstatus) und begrenzen Sie Wiederholungsversuche bei nicht vorübergehenden Fehlern. Verwenden Sie eindeutige Geschäftsschlüssel – verlassen Sie sich nicht standardmäßig auf die genau einmalige Zustellung.
Stellen Sie vor der Optimierung des Brokers eine einfache Frage: Überlebt Ihr Unternehmen, wenn diese Nachricht zweimal verarbeitet wird?
