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

OK, donc j'ai ce très rare scénario unique d'un site web PHP chargé et équilibré. La déception est - il n'a pas l'habitude d'être charge équilibrée. Maintenant, nous commençons à avoir des problèmes...

actuellement, le seul problème est avec les sessions PHP. Naturellement personne n'a pensé à ce problème au début, donc la configuration de la session PHP a été laissée à ses valeurs par défaut. Ainsi les deux serveurs ont leur propre petite réserve de fichiers de session, et malheur est l'utilisateur qui obtient la prochaine requête lancée à l'autre serveur, parce que cela n'a pas la session qu'il a créé sur le premier.

maintenant, J'ai lu le manuel de PHP sur la façon de résoudre cette situation. J'y ai trouvé la belle fonction de session_set_save_handler() . (Et, comme par hasard, ce sujet ) Soigné. Sauf que je vais appeler cette fonction dans toutes les pages du site. Et les développeurs de futures pages aurait à retenir de l'appeler tout le temps ainsi. Je me sens un peu maladroit, sans mentionner probablement violant une douzaine de bonnes pratiques de codage. Ce serait beaucoup plus agréable si je pouvais simplement retourner quelques options de configuration globale et Voilà - les sessions sont toutes magiquement stockées dans un DB ou une mémoire cache ou quelque chose.

des idées pour faire ça?


ajouté: pour clarifier - je m'attends à ce que ce soit une situation standard avec une solution standard. POUR INFO, J'ai une base de données MySQL disponible. Il y a certainement il doit y avoir un code prêt à l'emploi qui résout ça? Je peux, bien sûr, écrire mes propres trucs de sauvegarde de session et auto_prepend option pointée par Greg semble prometteur - mais qui se sentirait comme réinventer la roue. :P
, a Ajouté 2: L'équilibrage de la charge est DNS. Je ne sais pas comment ça marche, mais je suppose que ça devrait être quelque chose comme ce .
Ajouté 3: OK, je vois qu'une solution est d'utiliser auto_prepend option pour insérer un appel à session_set_save_handler() dans chaque script et écrire mon propre persister DB, peut-être jeter dans les appels à memcached pour une meilleure performance. Juste assez.

est-ce qu'il y a aussi un moyen pour que je puisse éviter de coder tout ça moi-même? Comme un plugin PHP célèbre et bien testé?

ajouté beaucoup, beaucoup plus tard: C'est la façon dont je suis allé à la fin: Comment implémenter correctement une session persister personnalisée en PHP + MySQL?

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

44
demandé sur Community 2009-06-15 11:52:36

10 réponses

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

un bon tutoriel pour cela peut être trouvé ici .

31
répondu Oliver Friedrich 2009-06-15 09:04:46

la façon dont nous traitons ceci est à travers memcached. Il suffit de changer le php.ini similaire à ce qui suit:

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

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

cette méthode ne nécessite aucun changement de code d'application.

18
répondu Doug Johnson 2012-10-24 15:20:12

vous n'avez pas mentionné quelle technologie vous utilisez pour l'équilibrage de charge (logiciel, matériel, etc.); mais dans tous les cas, la solution à votre problème est d'employer "sticky sessions" sur l'équilibreur de charge.

en résumé, cela signifie que lorsque la première requête d'un" nouveau " visiteur arrive, il lui est assigné un serveur spécifique du cluster: toutes les futures requêtes pour la durée de leur session sont alors dirigées vers ce serveur. Dans la pratique, cela signifie que les applications écrites pour fonctionner sur un seul serveur peuvent être adaptées à un environnement équilibré avec peu ou pas de modifications de code.

si vous utilisez un équilibreur matériel, tel qu'un périphérique Radware, alors les sessions sticky sont configurées dans le cadre de la configuration cluster. Périphériques matériels généralement vous donner plus de contrôle fin: comme le serveur qui un nouvel utilisateur est assigné (ils peuvent vérifier l'état de santé etc. et choisissez le plus sain et le moins utilisé de serveur), et plus de contrôle ce qui se passe quand un serveur tombe en panne et quitte le cluster. L'inconvénient des équilibreurs de matériel est le coût - mais ils en valent la peine imho.

pour ce qui est des équilibreurs de logiciels, cela se résume à ce que vous utilisez. Pour Apache Il ya la propriété stickysession sur mod_proxy-et beaucoup d'articles via google pour obtenir ce travail avec la session php ( par exemple )


Modifier: D'autres commentaires postée après la question originale, il semble que votre "équilibrage" se fait via le DNS du tournoi à la ronde, de sorte que ce qui précède ne s'appliquera probablement pas. Je m'abstiendrai de commenter davantage et de lancer une flamme contre le tournoi à la ronde dns.

6
répondu Ian 2009-06-15 08:59:53

la chose la plus facile à faire est de configurer votre équilibreur de charge pour toujours envoyer la même session au même serveur.

Si vous voulez toujours utiliser session_set_save_handler alors peut-être jeter un oeil à auto_prepend.

3
répondu Greg 2009-06-15 08:10:14

lorsque nous avons eu cette situation, nous avons mis en œuvre un code qui vit dans un en-tête commun.

essentiellement pour chaque page, Nous vérifions si nous connaissons l'Id de session. Si nous ne le faisons pas, nous vérifions si nous sommes dans la situation que vous décrivez, en vérifiant si nous avons stocké des données sur les lésions dans la base de données.Sinon, on vient juste de commencer une nouvelle session.

cela nécessite évidemment 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 puis il travaille sur OK.

1
répondu PaulJWilliams 2009-06-15 08:27:37

vous pouvez également essayer d'utiliser memcache comme gestionnaire de session

1
répondu 2009-06-15 08:51:34

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. Comme ça tu n'auras pas besoin de base de données.

Édité: vous pouvez également utiliser un service externe comme memcachedb (persistante et rapide) et stocker les informations de session dans l'index de memcachedb et l'identifier avec un hachage du contenu ou même L'ID de session.

1
répondu Khriz 2009-06-15 13:41:59

si vous avez le temps et que vous voulez toujours vérifier plus de solutions, jetez un oeil à http://redis4you.com/articles.php?id=01 ..

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

1
répondu Alex Moleiro 2016-08-12 08:36:01

peut-être trop tard, mais regardez ça: http://www.pureftpd.org/project/sharedance

Sharedance est un serveur haute performance pour centraliser les clés/données éphémères des paires sur des hôtes distants, sans frais généraux et sans la complexité D'un SQL la base de données.

il a été principalement conçu pour partager des caches et des sessions entre un pool de web serveur. L'accès à un serveur de sharedance est trivial grâce à un API PHP et il est compatible avec les attentes des gestionnaires de session PHP 4 et PHP 5.

0
répondu Claudio Bredfeldt 2013-12-03 10:29:30

quand il s'agit de la gestion de session php dans le Cluster D'équilibrage de charge, il est préférable d'avoir des Sessions collantes. Pour cela, demandez au réseau de datacenter qui maintient l'équilibreur de charge d'activer la session collante. Une fois que cela est activé, vous n'aurez pas besoin de vous soucier des sessions à la fin de php

0
répondu harigorana 2017-01-13 08:20:10