Message Queue mit Redis konfigurieren
Sofern mehrere Prozesse zur Abarbeitung von Nachrichten aus der Message Queue von Shopware 6 eingesetzt werden sollen, muss sichergestellt werden, dass identische Nachrichten nicht von denselben Consumern abgearbeitet werden. Hierzu ist die Verwendung einer Technologie notwendig, die das atomare Sperren von Nachrichten unterstützt. Hierfür eignen sich Redis oder RabbitMQ.
Voraussetzungen
- Redis-Server
- Shopware-Server
Vorbereitung in Shopware
Zunächst muss der Admin Worker deaktiviert werden, damit die Message Queue über einen Hintergrundprozess abgearbeitet werden kann. Mehr Informationen zum Deaktivieren des Admin Workers und der initialen Einrichtung über einen Supervisor-Prozess erfahren Sie hier: Shopware 6 Frontend Message Queue Worker deaktivieren.
Konfiguration der Shopware 6 Background Queue Worker
Die Konfiguration der Supervisor-Prozesse wird in folgenden Hilfecenter-Artikeln behandelt:
Konfiguration in Redis
Da Message-Queue-Jobs standardmäßig keine TTL wie in Redis besitzen, empfiehlt sich der Einsatz geeigneter Key-Eviction-Policies, deren Konfiguration im verlinkten Hilfecenter-Artikel beschrieben wird.
Wird die Message-Queue auf einem dedizierten Server betrieben, der ausschließlich diesem Zweck dient, kann problemlos die Standard-Policy noeviction verwendet werden.
Alternativ besteht die Möglichkeit, die Message-Queue gemeinsam mit dem App-Cache auf demselben Redis-Server zu betreiben. In diesem Fall sollte jedoch die Key-Eviction-Policy volatile-lru gewählt werden. Dadurch wird sichergestellt, dass bei Erreichen des maxmemory-Limits ausschließlich Cache-Einträge entfernt werden, da nur diese über eine TTL verfügen. Die Jobs der Message-Queue bleiben somit erhalten und werden nicht unbeabsichtigt gelöscht.
Konfiguration in Shopware
Erstellen Sie eine neue Konfigurationsdatei unter dem Pfad: config/packages/messenger.yaml. Mithilfe dieser Konfigurationsdatei kann der Shopware Messenger Transport-Dienst konfiguriert werden.
Fügen Sie anschließend folgenden Inhalt in die Datei ein:
Bis Shopware 6.4
parameters:
env(MESSENGER_CONSUMER_NAME): 'consumer'
framework:
messenger:
transports:
default:
dsn: "redis://%env(REDIS_HOST_MESSENGER)%:%env(REDIS_PORT_MESSENGER)%/messages/symfony/consumer-%env(MESSENGER_CONSUMER_NAME)%/?delete_after_ack=true&delete_after_reject=true&dbindex=%env(REDIS_DB_MESSENGER)%" Ab Shopware 6.5
Bestehenden Shopware-Scheduler-Prozess stoppen
supervisorctl stop shopware-scheduled-tasks:shopware-scheduled-tasks_00 Zur Überprüfung, ob die Message Queue leer ist, kann der folgende Befehl ab Shopware 6.5 verwendet werden:
bin/console messenger:stats Die Ausgabe sollte für jeden Transport einen 0 zeigen. Warten Sie in jedem Fall so lange, bis alle Jobs abgearbeitet sind.
Stoppen Sie anschließend alle Shopware Message-Queue Worker:
Der/Die Prozessname(n) können variieren und mit dem Befehl supervisorctl status eingesehen werden.
supervisorctl stop shopware-consumer:shopware-consumer_00 Anschließend kann die Message Queue seitens Shopware-Konfiguration auf Redis umgestellt werden:
# File: config/packages/messenger.yaml
parameters:
env(MESSENGER_CONSUMER_NAME): 'consumer'
framework:
messenger:
transports:
# shopware default transports
async:
dsn: "redis://%env(REDIS_HOST_MESSENGER)%:%env(REDIS_PORT_MESSENGER)%/messages_async?dbindex=%env(REDIS_DB_MESSENGER)%"
options:
consumer: "%env(MESSENGER_CONSUMER_NAME)%"
failed:
dsn: "redis://%env(REDIS_HOST_MESSENGER)%:%env(REDIS_PORT_MESSENGER)%/messages_failed?dbindex=%env(REDIS_DB_MESSENGER)%"
options:
consumer: "%env(MESSENGER_CONSUMER_NAME)%"
low_priority:
dsn: "redis://%env(REDIS_HOST_MESSENGER)%:%env(REDIS_PORT_MESSENGER)%/messages_low_priority?dbindex=%env(REDIS_DB_MESSENGER)%"
options:
consumer: "%env(MESSENGER_CONSUMER_NAME)%" Sofern weitere (zukünftig neue) Transports über Redis abgearbeitet werden müssen, müssen diese ebenfalls wie oben in der messenger.yaml vorgegeben konfiguriert werden.
Beschreibung eines Transports
Die von uns verwendete Transport-DSN Variante für Redis ist wie folgt aufgebaut:
<transport-name>:
dsn: "redis://<hostname>:<port>/<stream_key_name>?<options>"
options:
consumer: "custom-consumer-name-defined-in-environment-variable" Beispiel für async
async:
dsn: "redis://%env(REDIS_HOST_MESSENGER)%:%env(REDIS_PORT_MESSENGER)%/messages_async?dbindex=%env(REDIS_DB_MESSENGER)%"
options:
consumer: "%env(MESSENGER_CONSUMER_NAME)%" | Variable | Beschreibung |
|---|---|
| redis:// | Definiert das Protokoll für Symfony Redis-Transport |
| %(REDIS_HOST_MESSENGER)% | Hostname oder IP-Adresse zum Redis-Server Definition in der .env.local |
| %(REDIS_PORT_MESSENGER)% | TCP-Port für Redis-Verbindungen (Standard: 6379) Definition in der .env.local |
| messages_async | Redis Keyname (empfohlen, in dem Format nach dem Transport zu benennen) |
| %(MESSENGER_CONSUMER_NAME)% | Eindeutiger Name des Consumers (pro Consumer)Definition in den Supervisor-Prozessen |
| dbindex | Definiert den Redis Datenbank-Index |
| %(REDIS_DB_MESSENGER)% | Redis-Datenbank für den Messenger Definition in der .env.local |
Die Umgebungsvariable MESSENGER_CONSUMER_NAME muss durch den Supervisor-Service überschrieben werden, sodass auch die Ausführung von mehreren gleichzeitigen Consumern unterstützt werden kann.
Die hier verwendeten Variablen müssen anschließend in der Umgebungskonfiguration .env.local von Shopware hinzugefügt werden. Öffnen Sie hierzu die .env.local Datei im Shopware Root-Verzeichnis und ergänzen Sie folgenden Teil in der bestehenden Konfiguration:
# [...]
REDIS_HOST_MESSENGER=127.0.0.1
REDIS_PORT_MESSENGER=6379
REDIS_DB_MESSENGER=1 Prüfen Sie unbedingt vorher, ob die Redis Datenbank 1 frei ist und von keiner anderen Konfiguration verwendet wird.
Speichern Sie die Datei anschließend und leeren Sie den Shopware Cache über die Konsole:
bin/console cache:clear Starten Sie alle Supervisor-Prozesse mit folgendem Befehl wieder:
supervisorctl start all Anschließend wird die Message Queue über Redis ausgeführt.