web-dev-qa-db-fra.com

PHP sessions dans un cluster d'équilibrage de charge - comment?

D'accord, j'ai donc un scénario unique d'un site Web à charge équilibrée PHP. Le problème, c’est qu’il n’était pas équilibré auparavant. Maintenant, nous commençons à avoir des problèmes ...

Actuellement, le seul problème concerne les sessions PHP. Naturellement, personne n’ayant pensé à ce problème au début, la configuration de la session PHP a été laissée à ses valeurs par défaut. Ainsi, les deux serveurs ont leur propre réserve de fichiers de session. Par malheur, l'utilisateur qui envoie la demande suivante à l'autre serveur, car la session qu'il a créée n'a pas été créée.

Maintenant, je lis le manuel PHP sur la façon de résoudre cette situation. Là, j'ai trouvé la fonction intéressante de session_set_save_handler(). (Et comme par hasard, ce sujet sur SO) Neat. Sauf que je devrai appeler cette fonction dans toutes les pages du site. Et les développeurs de pages futures ne doivent pas oublier de l'appeler tout le temps. On se sent un peu maladroit, sans parler de violer probablement une douzaine de meilleures pratiques de codage. Ce serait beaucoup plus agréable si je pouvais simplement retourner une option de configuration globale et Voilà - les sessions sont toutes stockées comme par magie dans une base de données ou un cache de mémoire ou quelque chose du genre.

Auriez vous des idées pour faire ça?


Ajouté: Pour clarifier - je pense que cela sera une situation standard avec une solution standard. FYI - J'ai une base de données MySQL disponible. Il doit sûrement y avoir un code prêt à l’emploi qui résout tout cela. Je peux, bien sûr, écrire ma propre session pour enregistrer des éléments et l'option auto_prepend indiquée par Greg semble prometteuse - mais cela reviendrait à réinventer la roue. : P
Ajouté 2: L'équilibrage de la charge est basé sur DNS. Je ne suis pas sûr de savoir comment cela fonctionne, mais je suppose que cela devrait être quelque chose comme this .
Ajouté 3: OK, je vois qu’une solution consiste à utiliser l’option auto_prepend pour insérer un appel à session_set_save_handler() dans chaque script et écrire ma propre base de données, éventuellement en appelant memcached pour de meilleures performances. C'est suffisant.

Existe-t-il également un moyen d'éviter de coder tout cela moi-même? Vous aimez un plugin PHP célèbre et bien testé?

Beaucoup ajouté beaucoup plus tard: Voici comment je suis allé: Comment implémenter correctement une session personnalisée persister dans PHP + MySQL?

De plus, j'ai simplement inclus le gestionnaire de session manuellement dans toutes les pages.

45
Vilx-

Vous pouvez définir PHP pour gérer les sessions de la base de données, de sorte que tous vos serveurs partagent les mêmes informations de session car tous les serveurs utilisent la même base de données pour cela.

Un bon tutoriel pour cela peut être trouvé ici

32
Oliver Friedrich

La façon dont nous traitons ceci est à travers memcached. Tout ce qu'il faut, c'est changer le php.ini comme suit:

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

Nous utilisons AWS ElastiCache, le chemin du serveur est donc un domaine, mais je suis sûr qu'il serait similaire pour le memcached local. 

Cette méthode ne nécessite aucune modification du code de l'application.

19
Doug Johnson

Vous n'avez pas mentionné la technologie que vous utilisez pour l'équilibrage de charge (logiciel, matériel, etc.); mais dans tous les cas, la solution à votre problème consiste à utiliser des "sessions collantes" sur l'équilibreur de charge. 

En résumé, cela signifie que lorsque la première demande d'un "nouveau" visiteur arrive, un serveur spécifique du cluster lui est attribué: toutes les demandes futures relatives à la durée de sa session sont ensuite dirigées vers ce serveur. En pratique, cela signifie que les applications écrites pour fonctionner sur un seul serveur peuvent être mises à niveau vers un environnement équilibré avec zéro/peu de modifications de code.

Si vous utilisez un équilibreur matériel, tel qu'un périphérique Radware, les sessions collantes sont configurées dans le cadre de la configuration du cluster. Les périphériques matériels vous offrent généralement un contrôle plus précis: par exemple, le serveur auquel un nouvel utilisateur est affecté (ils peuvent vérifier l’état de santé, etc. et choisir le serveur le plus sain/le moins utilisé), et un contrôle accru de ce qui se produit échoue et quitte le cluster. L'inconvénient des équilibreurs matériels est leur coût - mais ils en valent la peine, à mon humble avis.

En ce qui concerne les équilibreurs de logiciels, cela dépend de ce que vous utilisez. Pour Apache, il y a la propriété stickysession sur mod_proxy - et de nombreux articles via Google pour que cela fonctionne avec la session php ( par exemple )


Edit: D'après d'autres commentaires postés après la question initiale, il semblerait que votre "équilibrage" se fasse via le DNS à tour de rôle, de sorte que ce qui précède ne s'appliquera probablement pas. Je m'abstiendrai de commenter davantage et de démarrer une flamme contre round robin dns.

7
Ian

La solution la plus simple consiste à configurer votre équilibreur de charge pour qu'il envoie toujours la même session au même serveur.

Si vous voulez toujours utiliser session_set_save_handler, jetez peut-être un coup d'œil à auto_prepend.

3
Greg

Si vous avez le temps et que vous souhaitez toujours vérifier d'autres solutions, consultez http://redis4you.com/articles.php?id=01 ..

En utilisant redis, vous êtes tolérant aux pannes. De mon point de vue, cela pourrait être mieux que les solutions memcache en raison de cette robustesse.

3
Alex Moleiro

Si vous utilisez des sessions php, vous pouvez partager avec NFS le répertoire/tmp, où je pense que les sessions sont stockées, entre tous les serveurs du cluster. De cette façon, vous n'avez pas besoin de base de données.

Modifié: vous pouvez également utiliser un service externe tel que memcachedb (persistant et rapide) et stocker les informations de session dans l'index memcachedb et l'identifier avec un hachage du contenu ou même l'identifiant de session.

2
Khriz

Lorsque nous avons eu cette situation, nous avons implémenté du code qui réside dans un en-tête commun.

Essentiellement, pour chaque page, nous vérifions si nous connaissons l'identifiant de session. Si nous ne vérifions pas si nous sommes dans la situation que vous décrivez, vérifiez si nous avons stocké des données de session dans la base de données. Sinon, nous commençons une nouvelle session.

Évidemment, cela nécessite que toutes les données pertinentes soient copiées dans la base de données, mais si vous encapsulez vos données de session dans une classe séparée, cela fonctionne correctement.

2
PaulJWilliams

vous pouvez aussi essayer d'utiliser memcache en tant que gestionnaire de session

1
maciek

Peut-être trop tard, mais regardez ceci: http://www.pureftpd.org/project/sharedance

Sharedance est un serveur hautes performances permettant de centraliser les clés/données éphémères paires sur des hôtes distants, sans la surcharge et la complexité d'un SQL base de données.

Il a été principalement conçu pour partager des caches et des sessions entre plusieurs sites Web les serveurs. L'accès à un serveur de mutualité est simple grâce à une simple API PHP et à il est compatible avec les attentes des gestionnaires de session PHP 4 et PHP 5.

1
Claudio Bredfeldt

Lorsqu'il est question de gérer les sessions php dans le cluster d'équilibrage de charge, il est préférable d'avoir des sessions collantes. Pour cela, demandez au réseau du centre de données qui gère l’équilibreur de charge d’activer la session persistante. Une fois que cela est activé, vous n'avez plus besoin de vous soucier des sessions php

0
harigorana