Question Perte de données de session aléatoire en PHP


Voici le problème auquel nous sommes confrontés depuis quelques semaines.

1 / Notre configuration

  • PHP 5.4 + MySQL
  • 2 serveurs dédiés, équilibrés en charge
  • Les sessions sont répliquées entre les 2 serveurs à l'aide de memcached
  • 3 applications en cours d'exécution sur ces serveurs:
    • Une application personnalisée, utilisant les paramètres de session php par défaut
    • Une autre application personnalisée, utilisant différents paramètres de session (nom du cookie, chemin d'accès)
    • Un CMS Wordpress

2 / Le problème

Le problème survient lors de notre première application.

Certains de nos utilisateurs ont signalé qu'ils sont parfois déconnectés au bout de quelques minutes (lorsque la session est configurée pour durer 3 heures). Cela peut leur arriver plusieurs fois dans la même journée, puis pas de déconnexion pendant quelques jours, mais le problème revient toujours. Jusqu'à présent, la fraction des utilisateurs impactés est faible, mais je voudrais résoudre ce problème avant qu'il ne se répande aux autres utilisateurs.

Le problème semble se poser à différents endroits de l'application, bien que nous ayons identifié 3 scénarios dans lesquels la plupart des erreurs se produisent:

  • Certains impliquent de soumettre un formulaire (la variable $ _SESSION est modifiée)
  • D'autres impliquent simplement l'ouverture d'une page contextuelle, sans modification des données de session

Nous avons essayé de reproduire les différents scénarios décrits par les utilisateurs: nous avons parfois pu le faire, mais la plupart du temps, nous n’avons aucun problème, ce qui rend difficile le débogage.

Autres notes :

  • Le problème est récent, cette application fonctionnait depuis des années sans aucun problème.
  • Il ne semble pas être lié à la charge de notre serveur, car le problème est toujours survenu pendant les vacances d'été lorsque notre trafic était faible
  • Il n'affecte qu'une session / des utilisateurs à la fois: tous les autres utilisateurs connectés simultanément ne rencontrent pas ce problème.
  • Le problème est survenu sur tous les navigateurs (IE, Firefox, Chrome)

3 / Analyse technique

Lorsqu'une déconnexion se produit, l'utilisateur est redirigé vers une page "Votre session a expiré ou vous n'avez pas le droit de consulter". Lorsque cette page est chargée, nous recevons un e-mail technique contenant un vidage de la variable $ _SESSION.

Lorsqu'une session expire normalement, le courrier électronique que nous recevons indique que la variable $ _SESSION est vide (comportement normal). Quand une déconnexion inattendue se produit, ce qui est intéressant, c'est que $ _SESSION n'est pas entièrement vide: sur les ~ 20 éléments que contient le tableau, il n'en reste qu'un (toujours le même).

Cela signifie donc que la session n'est pas expirée, mais qu'il ne reste pas assez de données pour "identifier" l'utilisateur, d'où la page "sans droits" affichée. En guise de confirmation lorsque cela se produit, nous pouvons vérifier dans memcached que cette session contient encore des données.

Ce sont les causes de problèmes potentiels que nous avons identifiées jusqu'à présent et ce que nous avons fait pour les exclure:

  • Memcached indique entre 70 et 80% d'espace libre, nous ne pensons donc pas que ce soit le problème.
  • Nous avons supprimé Memcached et sommes retournés à l’utilisation d’un répertoire partagé NFS pour les fichiers de session: le problème s’est aggravé. Cela indiquerait un bogue applicatif, car NFS étant plus lent à écrire des données, la perte de session se produirait plus souvent.
  • Nous avons parcouru tous les différents forums (y compris SO) à propos de la perte de données de session PHP et examiné notre code en conséquence. La base de code est grande, mais nous avons utilisé des outils et des scripts automatisés pour éviter de manquer un fichier.
    • session_start () est appelée au début de chaque page.
    • exit () est appelé après chaque en-tête ("Location ...")
    • register_globals est désactivé
  • Nous avons testé les interactions possibles entre nos 2 autres applications et la problématique, mais elles ne partagent aucun code, aucune base de données ni aucune gestion de session. Rien n'y est identifié.
  • Nous avons analysé nos journaux d’accès aux heures des déconnexions, pour vérifier les comportements: pas de chance non plus.

Donc, nous n'avons aucune idée de ce qui cause ce problème, car il semble se produire au hasard, donc mes questions sont les suivantes:

  • Le problème pourrait venir de notre code: avons-nous manqué quelque chose à vérifier? Cette solution semble improbable car le code fonctionne la plupart du temps pour tous nos utilisateurs, mais je le considère toujours.
  • Le problème pourrait provenir d'une autre application / processus qui "viderait" une partie du tableau de variables de session. Nous avons également revu le code des autres applications, mais nous n’avons rien trouvé qui puisse provoquer cela. Et si un autre processus le fait, pourquoi ne viderait-il que certaines sessions et pas toutes?

Merci de votre aide.


17
2017-09-03 11:21


origine


Réponses:


Je ne pense pas que vous obtiendrez une réponse définitive à votre question. Il y a trop de causes probables et vous n'avez pas montré de code.

Pourtant, je suppose que vous avez memcached.sess_locking Désactivé, ou si vous avez une implémentation de session personnalisée - qu'il ne met pas du tout en oeuvre le verrouillage.
Finalement, cela conduit à une condition de concurrence entre deux requêtes HTTP simultanées.

Mon hypothèse est basée sur le mauvais conseil souvent vu d'éteindre les serrures ou de les libérer dès que possible, afin d'obtenir des performances plus élevées.


1
2017-09-03 12:33



Si ce problème "soudain" s'est produit, vérifiez ce qui a changé. Avez-vous travaillé sur l'application? Si tel est le cas, vérifiez le code engagé (vous avez parlé des outils automatisés, donc je m'attends à ce qu'il y ait un référentiel qui permette une recherche précise des modifications de code). Avez-vous changé quelque chose sur le serveur? Comme la mise à niveau du logiciel, mettre à niveau / modifier le matériel, apporter des modifications aux deux autres applications? Une chose qui a surgi à l'esprit, avez-vous vérifié les lecteurs que vous utilisez pour la mise en cache? Cela pourrait être une partie corrompue du système de fichiers. Ce qui expliquerait la partie utilisateur aléatoire.

J'ai toujours des choses à faire:

  • Essayez de déterminer le moment de la première occurrence aussi précis que possible. À mon travail, cela déclenche parfois quelqu'un qui dit: "Ouais, cela pourrait avoir un rapport avec le moment où j'ai changé / mis à jour / créé ceci ou cela", cela pourrait donc aider. D'un autre côté, cela prend parfois des jours, des semaines ou plus avant que quelque chose ne soit remarqué, alors commencez à élargir ce délai si rien ne se passe.
  • Vous avez déjà quelques scénarios, trouver le facteur commundans ces. S'ils ne partagent aucun code, arrêtez d'y regarder. S'ils partagent la recherche de code là-bas. Bien sûr, le partage (partiel) de cette partie peut nous permettre de vous aider dans votre recherche.
  • Faire une recherche organisée. Je fais généralement la vérification de l'application principale lorsque je travaille le plus sur l'application (ou même mieux lorsque je l'ai créée). Un collègue vérifiera les applications environnantes susceptibles d'avoir une influence. Dans votre cas, ces 2 autres applications. Enfin, notre sysadmin vérifiera la présence de logiciels nouvellement installés ou mis à jour sur le (s) serveur (s) et vérifiera également auprès de notre réseau si quelque chose a changé au niveau du matériel ou du réseau (pour les autres, cela pourrait être le fournisseur d'hébergement).

0
2017-09-09 17:00



Cela pourrait être aussi simple qu'un plugin WordPress qui utilise des sessions et des appels soit session_name() ou session_id() avec une valeur différente, chevauchant vos applications personnalisées avec les paramètres de session par défaut.

Comme WordPress n'utilise pas de sessions, les plug-ins sont souvent écrits dans la perspective d'avoir des sessions libres. Je viens de faire une recherche sur un site de test WordPress et j'ai trouvé des sessions utilisées dans un plugin de galerie, un plugin pour mettre une image de fond sur la page, un plugin de panier et un plugin nécessaire page admin à un autre.


0
2018-01-02 01:37