para - Pérdida de datos de sesión aleatoria en PHP
generar numero aleatorio php sin repetir (3)
Aquí está el problema que hemos estado enfrentando durante las últimas semanas.
1 / Nuestra configuración
- PHP 5.4 + MySQL
- 2 servidores dedicados, carga equilibrada
- Las sesiones se replican entre los 2 servidores usando memcached
- 3 aplicaciones que se ejecutan en estos servidores:
- Una aplicación desarrollada a medida, utilizando la configuración de sesión php predeterminada
- Otra aplicación desarrollada a medida, que utiliza diferentes configuraciones de sesión (nombre de cookie, ruta)
- Un CMS de Wordpress
2 / El problema
El problema se produce en nuestra primera aplicación.
Algunos de nuestros usuarios informaron que a veces se desconectan después de unos minutos (cuando la sesión está configurada para durar 3 horas). Les puede pasar varias veces en el mismo día, luego no hay desconexión durante unos días, pero el problema siempre vuelve. Hasta ahora, la fracción de usuarios afectados es pequeña, pero me gustaría resolver esto antes de que se "extienda" a otros usuarios.
El problema parece ocurrir en diferentes lugares de la aplicación, aunque hemos identificado 3 escenarios donde se producen la mayoría de los errores:
- Algunos implican enviar un formulario (se modifica la variable $ _SESSION)
- Otros simplemente implican abrir una página emergente, sin modificar los datos de la sesión
Hemos intentado reproducir los diferentes escenarios descritos por los usuarios: a veces hemos podido, pero la mayoría de las veces no tenemos ningún problema, lo que dificulta la depuración.
Otras notas :
- El problema es reciente, esta aplicación ha estado funcionando durante años sin ningún problema.
- No parece estar relacionado con la carga de nuestro servidor, porque el problema aún se presentaba durante las vacaciones de verano cuando el tráfico era bajo.
- Solo afecta a una sesión / usuarios a la vez: todos los demás usuarios conectados al mismo tiempo no experimentan este problema
- El problema ocurrió en todos los diferentes navegadores (IE, Firefox, Chrome)
3 / Análisis técnico
Cuando se produce una desconexión, el usuario es redirigido a una página "Su sesión ha caducado o no tiene derecho a ver". Cuando se carga esta página, recibimos un correo electrónico técnico con un volcado de la variable $ _SESSION.
Cuando una sesión expira de la manera normal, el correo electrónico que recibimos muestra que la variable $ _SESSION está vacía (comportamiento normal). Cuando ocurre una desconexión inesperada, lo interesante es que $ _SESSION no está completamente vacío: de los ~ 20 elementos que contiene la matriz, solo queda uno (siempre lo mismo).
Entonces, esto significaría que la sesión no ha caducado, pero no se dejan suficientes datos para "identificar" al usuario, por lo tanto, se muestra la página "sin derechos". Como confirmación cuando esto ocurre, podemos verificar en memcached que esta sesión aún tiene algunos datos.
Estas son las posibles causas de problemas que hemos identificado hasta ahora, y lo que hemos hecho para descartarlas:
- Memcached indica entre 70 y 80% de espacio libre, por lo que no creemos que sea el problema.
- Eliminamos Memcached y volvimos a usar un directorio compartido de NFS para los archivos de sesión: el problema empeoró. Esto apuntaría a un error de aplicación, ya que NFS es más lento para escribir datos y la pérdida de sesión ocurre con más frecuencia.
- Hemos examinado todos los diferentes foros (incluido el SO) hablando sobre la pérdida de datos de la sesión de PHP y revisamos nuestro código en consecuencia. El código base es grande, pero hemos utilizado herramientas y scripts automatizados para evitar perder un archivo.
- session_start () se llama al principio de cada página.
- Se llama a exit () después de cada encabezado ("Ubicación ...")
- register_globals está desactivado
- Hemos probado las posibles interracciones entre nuestras otras 2 aplicaciones y la problemática, aunque no comparten ningún código, base de datos o manejo de sesiones. Nada identificado allí.
- Hemos analizado nuestros registros de acceso en torno a los tiempos de las desconexiones, para verificar los patrones de comportamiento: aquí tampoco hay suerte.
Entonces, no tenemos idea de qué causa este problema, ya que parece ocurrir al azar, por lo que mis preguntas son:
- El problema podría venir de nuestro código: ¿perdimos algo para verificar? Esta solución parece poco probable ya que el código funciona la mayor parte del tiempo para todos nuestros usuarios, pero todavía lo estoy considerando.
- El problema podría provenir de otra aplicación / proceso que "vaciaría" parte de la matriz de variables de sesión. También hemos revisado el código de las otras aplicaciones, pero no encontramos nada que pudiera causar esto. Y si otro proceso está haciendo esto, ¿por qué solo se vacían algunas sesiones y no todas?
Gracias por tu ayuda.
Podría ser tan simple como un complemento de WordPress que usa sesiones y llama a session_name()
o a session_id()
con un valor diferente, superponiendo sus aplicaciones personalizadas con la configuración de sesión predeterminada.
Dado que WordPress no utiliza sesiones, los complementos a menudo se escriben desde la perspectiva de tener rienda suelta con las sesiones. Acabo de hacer una búsqueda en un sitio de prueba de WordPress y encontré sesiones usadas en un complemento de la galería, un complemento para poner una imagen de fondo en la página, un complemento del carrito de compras y un complemento que estaba escribiendo y que necesitaba para cargar un archivo cargado. página de administración a otra.
Si se produjo este problema "de repente", compruebe lo que ha cambiado. ¿Hiciste algún trabajo en la aplicación? Si es así, verifique el código confirmado (usted habló sobre herramientas automatizadas, así que espero que haya un repositorio que permita un descubrimiento preciso de los cambios en el código). ¿Cambiaste algo en el servidor? ¿Como actualizar el software, actualizar / cambiar el hardware, hacer cambios en las otras dos aplicaciones? Una cosa que me vino a la mente, ¿comprobó las unidades que usa para el almacenamiento en caché? Podría ser una parte dañada del sistema de archivos. Lo que explicaría la parte de usuario aleatorio.
Un par de cosas a las que siempre me ha llegado es:
- Trate de determinar el momento de la primera aparición lo más preciso posible . En mi trabajo, esto ocasionalmente provoca que alguien diga "oh, sí, eso podría tener que ver con cuando cambié / actualicé / creé esto o aquello", por lo que esto podría ayudar. Por otro lado, a veces puede tomar días, semanas o más antes de que se note algo, así que comience a expandir ese marco de tiempo si no aparece nada.
- Ya tienes un par de escenarios, encuentra el factor común en estos. Si no comparten ningún código, dejen de mirar allí. Si comparten código buscar allí. Por supuesto, compartirlo (parte de) aquí podría permitirnos ayudarlo a buscar.
- Hacer una búsqueda organizada . Por lo general, hago la comprobación de la aplicación principal cuando soy el que más trabaja en la aplicación (o incluso mejor cuando la creé). Un colega comprobará las aplicaciones circundantes que puedan influir en él. En tu caso esas 2 otras aplicaciones. Finalmente, nuestro administrador del sistema buscará el software recién instalado o actualizado en el (los) servidor (es) y también verificará con los miembros de nuestra red si hay algún cambio en el hardware o relacionado con la red (para otras personas, este podría ser el proveedor de alojamiento).
No creo que obtendrás una respuesta definitiva a tu pregunta. Hay demasiadas causas probables y no has mostrado ningún código.
Sin embargo, mi conjetura es que tienes memcached.sess_locking desactivado, o si tienes una implementación de sesión personalizada, eso no implementa el bloqueo en absoluto.
Eventualmente, esto lleva a una condición de carrera entre dos solicitudes HTTP simultáneas.
Mi conjetura se basa en el mal visto consejo para desactivar los bloqueos o liberarlos lo antes posible, a fin de lograr un mayor rendimiento.