PHP-Sessions sind ein elementarer Bestandteil von Shopware 6 und zwingend notwendig, um Informationen über mehrere Seitenaufrufe hinweg zu speichern. Aber wie verwendet Shopware Sessions und welche Optimierungsmöglichkeiten gibt es? Weiter unten erfährst Du, wie Du die Session-Ladezeiten mit Redis optimieren kannst.
Wenn Du bereits weißt, was eine Session ist, kannst Du hier zum Teil der Optimierung skippen.
Was ist eine Session?
Eine Session in PHP ist eine Möglichkeit, Benutzerdaten über mehrere Seitenaufrufe hinweg zu speichern und wiederzuverwenden. Sie ist besonders nützlich, wenn Daten wie der Login-Status eines Kunden oder Warenkorbinhalte über eine gesamte „Sitzung“ des Nutzers hinweg erhalten bleiben sollen, ohne dass diese Daten jedes Mal neu übergeben werden müssen.
Aus technischer Sicht wird eine Session in PHP gestartet, indem der Befehl session_start()
aufgerufen wird. Dieser erstellt eine eindeutige Session-ID, die als Cookie im Browser des Nutzers gespeichert wird. Über diese Session-ID kann der Server die zugehörigen Sitzungsdaten abzurufen, wenn der Nutzer auf eine neue Seite zugreift. Die Session-Daten werden auf dem Server gespeichert und über die Session-ID mit dem Nutzer verbunden, sodass private Informationen geschützt und sicher bleiben.
Sessions in Symfony
Da Shopware 6 auf Symfony aufgebaut ist, regelt Symfony das Starten der Session automatisch. Genauere Informationen, wie Symfony Sessions verwendet, findest Du in diesem Beitrag.
Vereinfacht gesagt wird bei jedem Request über das kernel.request Event mithilfe einer Session-Factory eine neue Session-Instanz gestartet und im Request verfügbar gemacht. Shopware kann dann relativ einfach im Code auf die Session aus dem Request zugreifen und die nötigen Daten abfragen (z.B. bin ich als Kunde eingeloggt o.Ä.).
Vorteile und Sicherheit
Sessions in PHP bieten eine komfortable Möglichkeit zur Verwaltung von Benutzerdaten ohne den Einsatz von Cookies allein. Da die Daten auf dem Server gespeichert werden, sind sie sicherer vor Manipulationen durch den Nutzer.
Welche verschiedenen Speichermöglichkeiten gibt es für Sessions?
Symfony & Shopware 6 speichern ihre Sessions standardmäßig in Dateien auf der Festplatte. Für Testsysteme oder für kleine Shops mit wenig Traffic ist diese Art und Weise Sessions zu speichern auch vollkommen ausreichend. Allerdings kann bei viel Traffic das ständige Lesen und Schreiben der Daten auf der Festplatte schnell zu einem Bottleneck werden. Auch bei einem Cluster-Setup, bei dem sich mehrere Application-Server einen Session-Pool teilen müssen, würde das Standard Session Handling Probleme bereiten. Welche anderen Möglichkeiten bietet Symfony bzw. Shopware also, die Sessions auszulagern?
Sessions in einer externen Datenbank
Symfony kann Sessions in verschiedenen Datenbanken speichern (relationale, NoSQL und Key-Value-Datenbanken), empfiehlt jedoch Key-Value-Datenbanken wie Redis, um die beste Leistung zu erzielen.
Redis als Session Handler für Shopware 6
Der wohl bekannteste Session-Handler im Zusammenhang mit Shopware ist Redis. Beim Session-Handling über Redis wird Redis als Speicher für die Session-Daten genutzt, anstatt diese lokal auf dem Dateisystem oder in einer relationalen Datenbank zu speichern.
Redis bietet gerade bei hoher Last deutliche Performance-Vorteile. Da die Daten im Arbeitsspeicher und nicht auf der Festplatte liegen, können sie ohne Performance-Verluste abgerufen und gespeichert werden, was für eine deutliche Verbesserung der Ladezeiten sorgt.
Die genaue Zahl der Verbesserung hängt natürlich stark davon ab, wie viel Last auf dem Server und damit der Festplatte liegt. Bei einigen Kunden hatte ich aber schon Fälle gehabt, bei denen das Starten der Session über die Festplatte fast eine Sekunde gebraucht hat.
Auch bei einem Cluster-Setup kann über mehrere Application-Server auf die selbe Redis-Instanz zugegriffen werden, sodass es nur einen gemeinsamen Ort für Sessions gibt und keine Probleme auftreten können.
Schritt 1 – Software installieren
Im ersten Schritt müsstet ihr sicherstellen, dass Redis auf Eurem Server installiert und eingerichtet ist. Sprecht hierzu am besten mit Eurem Hoster. Bei unserem Lieblingshoster Maxcluster lässt sich Redis ganz leicht über die Serverkonfiguration installieren. Mit der “Optimiert für Sessions”-Vorlage läuft die Einrichtung auch sehr leicht.
Ob Redis richtig eingerichtet und verfügbar ist, könnt ihr über den Befehl redis-cli prüfen. Gebt ihr hier PING ein, solltet ihr ein PONG zurückbekommen.
Schritt 2 – Redis bei Shopware konfigurieren
Um Redis bei Shopware zu konfigurieren und letztendlich verfügbar zu machen, gibt es zwei verschiedene Möglichkeiten.
Zum einen können wir den Redis-dsn direkt in der php.ini hinterlegen, damit der Session-Handler in PHP konfiguriert ist. Diese Konfiguration könnte so aussehen:
session.save_handler = redis
session.save_path = "tcp://host:6379"
Da die Konfiguration in der php.ini meist über den Hoster geht, präferiere ich eigentlich immer den Weg über die Shopware-Konfiguration. Hierfür legen wir folgende Datei neu an: config/packages/redis.yml
In dieser Config-Datei können wir folgenden Inhalt hinterlegen:
# config/packages/redis.yml
framework:
session:
handler_id: "redis://host:port"
Abschließend sollte der Cache einmal geleert werden.
Schritt 3 – Testen, ob Redis als Session-Handler funktioniert
Um die Einrichtung abzuschließen, teste ich am Ende, ob Redis funktioniert. Hierfür gehe ich grundsätzlich in den Shop und teste ein paar Funktionen, bei denen Sessions eingesetzt werden, also z.B. den Login oder das Hinzufügen von Artikeln zum Warenkorb.
Anschließend gehe ich wieder in der Konsole über redis-cli in die Redis-Instanz hinein und führe “KEYS *” aus. Da ich die Session-Funktionen im Shop getestet habe, sollte dieser Befehl mir mindestens eine Session-ID zurückgeben. Wenn redis im Prod-System eingerichtet wurde, kann es auch sein, dass hier bereits nach kurzer Zeit mehrere IDs zurückgegeben werden.
Schritt 4 – optionale Migration
Symfony bietet die Möglichkeit, die Session-IDs bzw. Inhalte zu migrieren. Sobald wir nämlich Redis integrieren, gehen die bisherigen File-Session-Daten verloren. Ein Kunde, der Artikel im Warenkorb hatte, hat dann plötzlich einen leeren Warenkorb.
Wie die Migration genau funktioniert, könnt ihr in der Doku von Symfony nachlesen.
In meinen bisherigen Einrichtungen hatte sich eine Migration oft nicht gelohnt. Ich würde hierbei empfehlen, die Umstellung z.B. frühmorgens zu machen, sodass im Idealfall wenig bis keine Kunden im Shop unterwegs sind.
Andere mögliche Session-Handler
Symfony bietet von Haus aus noch viele weitere mögliche Session-Handler, die wir relativ einfach konfigurieren können. Da Redis aber eigentlich keine Nachteile hat, gehe ich nicht genauer auf die einzelnen Handler ein und stelle sie nur kurz vor. Grundsätzlich würde ich aber jedem Shop Redis empfehlen.
- PdoSessionHandler: Über den PdoSessionHandler können Sessions in der MySQL-Datenbank gespeichert werden. Gerade bei viel Traffic würden wir damit aber nur mehr Last auf die Datenbank lenken. Daher in den meisten Fällen nicht empfehlenswert.
- MemcachedSessionHandler: Memcached funktioniert ähnlich wie Redis. Grundsätzlich könntet ihr auch Memcached verwenden und erzielt damit das gleiche Ergebnis. Falls Euer Hoster kein Redis, aber dafür Memcached hat, könnt ihr das Tool gerne benuzten.
- MongoDbSessionHandler: Hierbei werden die Session-Daten in einer MondoDB gespeichert. Ein interessanter Ansatz, aber eigentlich auch nicht nötig, da wir ja bereits Redis haben.
Session TTL erhöhen
Symfony verwendet standardmäßig PHPs session.gc_maxlifetime
-Einstellung als Sitzungsdauer. Wenn Du Sitzungen in z.B. Redis speicherst, kannst Du auch Deine eigene TTL in der Framework-Konfiguration oder sogar zur Laufzeit festlegen.
Ein Beispiel, wie man die TTL festlegen kann, findest Du hier. Die Konfiguration kannst Du in der oben angelegten redis.yaml hinterlegen.
Neben der Session gibt es natürlich auch viele andere Stellen, an denen wir unseren Shopware 6 Shop optimieren können. Erfahre hier, wie Du Deine Datenbank optimiert einstellst.