wake-up-neo.com

PHP Sitzungen in einem Lastausgleichs-Cluster - wie?

OK, ich habe also dieses seltene Szenario einer ausbalancierten PHP Website. Der Scheißer ist - es war früher kein Lastausgleich. Jetzt beginnen wir Probleme zu bekommen ...

Derzeit ist das einzige Problem bei PHP -Sitzungen. Natürlich dachte niemand zuerst an dieses Problem, daher blieb die PHP - Sitzungskonfiguration auf ihren Standardwerten. Daher haben beide Server ihren eigenen kleinen Vorrat an Sitzungsdateien, und wehe ist der Benutzer, der die nächste Anforderung an den anderen Server geworfen bekommt, weil die Sitzung, die er für den ersten erstellt hat, nicht vorhanden ist.

Nun habe ich im PHP Handbuch gelesen, wie man diese Situation lösen kann. Dort fand ich die Nice-Funktion von session_set_save_handler(). (Und zufällig dieses Thema zu SO) Neat. Nur muss ich diese Funktion auf allen Seiten der Website aufrufen. Und Entwickler zukünftiger Seiten müssten auch immer daran denken, es zu nennen. Fühlt sich irgendwie unbeholfen an, ganz zu schweigen davon, dass ein Dutzend der besten Kodierungsmethoden verletzt wird. Es wäre viel schöner, wenn ich einfach eine globale Konfigurationsoption umdrehen würde und Voilà - die Sitzungen werden alle magisch in einer DB oder einem Speicher-Cache oder etwas anderem gespeichert.

Irgendwelche Ideen, wie das geht?


Hinzugefügt: Zur Klarstellung - ich gehe davon aus, dass dies bei einer Standardlösung eine Standardsituation ist. FYI - Ich habe eine MySQL-Datenbank zur Verfügung. Sicherlich muss es einsatzbereiten Code geben, der dieses Problem löst. Ich kann natürlich mein eigenes Session-Save-Zeug schreiben und die auto_prepend-Option, auf die Greg hingewiesen hat, scheint vielversprechend zu sein - aber das fühlt sich an, als würde man das Rad neu erfinden. : P
Added 2: Der Lastausgleich basiert auf DNS. Ich bin nicht sicher, wie das funktioniert, aber ich denke, es sollte etwas wie this ..__ sein.
Added 3: OK, ich sehe, dass es eine Lösung ist, die auto_prepend-Option zu verwenden, um einen Aufruf von session_set_save_handler() in jedes Skript einzufügen und meine eigene DB-Datenbank zu schreiben, wobei zur Verbesserung der Leistung vielleicht Aufrufe in memcached ausgelöst wird. Meinetwegen.

Gibt es auch einen Weg, wie ich es vermeiden könnte, das alles selbst zu codieren? Wie irgendein berühmtes und getestetes PHP Plugin?

Viel, viel später hinzugefügt: So bin ich am Ende gegangen: Wie implementiere ich eine angepasste Sitzung in PHP + MySQL richtig?

Außerdem habe ich den Session-Handler einfach in alle Seiten manuell eingefügt.

45
Vilx-

Sie können PHP so einstellen, dass die Sitzungen in der Datenbank verarbeitet werden, sodass alle Server dieselben Sitzungsinformationen verwenden, da alle Server dieselbe Datenbank dafür verwenden.

Eine gute Anleitung dazu finden Sie hier

32

Die Art und Weise, wie wir damit umgehen, ist durch Memcached. Es genügt, die php.ini ähnlich wie folgt zu ändern:

session.save_handler = memcache
session.save_path = "tcp://path.to.memcached.server:11211"

Wir verwenden AWS ElastiCache, der Serverpfad ist also eine Domäne, aber ich bin mir sicher, dass er auch für lokales Memcached ähnlich ist. 

Diese Methode erfordert keine Änderungen des Anwendungscodes.

19
Doug Johnson

Sie erwähnen nicht, welche Technologie Sie zum Lastausgleich verwenden (Software, Hardware usw.). In jedem Fall besteht die Lösung Ihres Problems jedoch darin, "sticky session" auf dem Load Balancer einzusetzen. 

Zusammenfassend bedeutet dies, dass wenn die erste Anforderung eines "neuen" Besuchers eingeht, dieser einem bestimmten Server aus dem Cluster zugewiesen wird: Alle zukünftigen Anforderungen für die Dauer ihrer Sitzung werden dann an diesen Server weitergeleitet. In der Praxis bedeutet dies, dass Anwendungen, die auf einem einzelnen Server ausgeführt werden, auf eine ausgeglichene Umgebung mit null/wenigen Codeänderungen hochskaliert werden können.

Wenn Sie einen Hardware-Balancer wie ein Radware-Gerät verwenden, werden die Dauersitzungen als Teil des Cluster-Setups konfiguriert. Hardwaregeräte bieten Ihnen in der Regel eine feinere Kontrolle, z. B., welchem ​​Server ein neuer Benutzer zugewiesen ist (er kann den Integritätsstatus überprüfen und den am meisten gesunden/am wenigsten genutzten Server auswählen) und mehr Kontrolle darüber, was bei einem Server passiert schlägt fehl und fällt aus dem Cluster heraus. Der Nachteil von Hardware-Balancern sind die Kosten - aber sie lohnen sich imho.

Bei Software-Balancern kommt es darauf an, was Sie verwenden. Für Apache gibt es auf mod_proxy die stickysession -Eigenschaft - und viele Artikel über Google, damit dies mit der PHP-Sitzung funktioniert ( zum Beispiel ).


Bearbeiten: Von anderen Kommentaren, die nach der ursprünglichen Frage gepostet wurden, klingt das so, als ob Ihr "Balancing" über Round Robin DNS erfolgt. Die obigen Angaben werden wahrscheinlich nicht zutreffen. Ich werde nicht weiter kommentieren und eine Flamme gegen Round Robin dns starten.

7
Ian

Am einfachsten ist es, Ihren Load Balancer so zu konfigurieren, dass immer dieselbe Sitzung an denselben Server gesendet wird.

Wenn Sie noch session_set_save_handler verwenden möchten, schauen Sie sich vielleicht auto_prepend an.

3
Greg

Wenn Sie Zeit haben und immer noch nach Lösungen suchen, schauen Sie unter http://redis4you.com/articles.php?id=01 .. nach.

Mit redis sind Sie fehlertolerant. Aus meiner Sicht könnte es aufgrund dieser Robustheit besser sein als Memcache-Lösungen.

3
Alex Moleiro

Wenn Sie PHP-Sitzungen verwenden, können Sie mit NFS das Verzeichnis/tmp freigeben, in dem die Sitzungen meines Erachtens zwischen allen Servern im Cluster gespeichert sind. Auf diese Weise brauchen Sie keine Datenbank.

Bearbeitet: Sie können auch einen externen Dienst wie memcachedb (persistent und schnell) verwenden und die Sitzungsinformationen im memcachedb-Index speichern und mit einem Hash des Inhalts oder sogar der Sitzungs-ID identifizieren.

2
Khriz

In dieser Situation haben wir Code implementiert, der sich in einem gemeinsamen Header befindet.

Im Wesentlichen überprüfen wir für jede Seite, ob wir die Sitzungs-ID kennen. Wenn wir nicht prüfen, ob wir uns in der Situation befinden, die Sie beschreiben, prüfen wir, ob wir Sitzungsdaten in der Datenbank gespeichert haben. Andernfalls starten wir einfach eine neue Sitzung.

Offensichtlich müssen dazu alle relevanten Daten in die DB kopiert werden. Wenn Sie jedoch Ihre Sitzungsdaten in einer separaten Klasse kapseln, funktioniert es in Ordnung.

2
PaulJWilliams

sie können auch versuchen, Memcache als Session-Handler zu verwenden

1
maciek

Könnte zu spät sein, aber überprüfen Sie dies: http://www.pureftpd.org/project/sharedance

Sharedance ist ein Hochleistungsserver zur Zentralisierung kurzlebiger Schlüssel/Daten Paare auf Remote-Hosts, ohne den Overhead und die Komplexität eines SQL Datenbank.

Es wurde hauptsächlich entwickelt, um Caches und Sitzungen zwischen einem Pool von Web zu teilen Server. Der Zugriff auf einen Sharedance-Server ist über eine einfache PHP API und .__ trivial. es ist kompatibel mit den Erwartungen von PHP 4 und PHP 5 Session-Handlern.

1

Wenn es um die Handhabung von PHP-Sitzungen im Load-Balancing-Cluster geht, sollten Sie am besten Sticky-Sitzungen durchführen. Bitten Sie dazu das Netzwerk des Rechenzentrums, das den Lastausgleicher verwaltet, um die Sticky-Sitzung zu aktivieren. Sobald dies aktiviert ist, müssen Sie sich keine Gedanken über Sitzungen am Ende von PHP machen

0
harigorana