session - sesiones - ¿Cómo administrar las variables de sesión en un clúster web?
session php (8)
Las variables de sesión normalmente se guardan en la memoria RAM del servidor web.
En un clúster, cada solicitud realizada por un cliente puede ser manejada por un nodo de clúster diferente. ¡¿derecho?!
Entonces, en este caso ...
- ¿Qué pasa con las variables de sesión? ¿No están almacenados en la memoria RAM de los nodos?
- ¿Cómo manejarán los otros nodos mi solicitud correctamente si no tiene mis variables de sesión, o al menos todo?
- Este problema es tratado por el servidor web (Apache, IIS) o por el tiempo de ejecución del lenguaje (PHP, ASP.NET, Ruby, JSP)?
EDIT: ¿Hay alguna solución para Classic ASP ?
Como con todo tipo de cosas, "depende".
Hay diferentes soluciones y enfoques.
Como se mencionó, existe el concepto de un almacén centralizado para el estado de la sesión (base de datos, memcached, sistema de archivos compartidos, etc.).
También hay sistemas de caché de todo el clúster disponibles que hacen que los datos locales estén disponibles para todas las máquinas del clúster. Conceptualmente, es similar al almacén de estado de sesión centralizado, pero estos datos no son persistentes. Más bien, vive dentro de los nodos individuales y se replica utilizando algún mecanismo proporcionado por su proveedor.
Otro método es fijar el servidor. Cuando un cliente golpea el clúster por primera vez, algún mecanismo (por lo general, un equilibrador de carga al frente del clúster) fija al cliente en un servidor específico. En una vida útil típica del cliente, ese cliente pasará todo su tiempo en una sola máquina.
Para el mecanismo de conmutación por error, cada máquina del clúster está emparejada con otra máquina, por lo que cualquier cambio de sesión se comparte con la máquina emparejada. Si la máquina anclada del cliente encuentra un problema, el cliente golpeará a otra máquina. En este punto, tal vez debido a las cookies, la máquina nueva ve que no es la máquina original para el cliente, por lo que hace sonar tanto la máquina original como la máquina emparejada para los datos de sesión de los clientes.
En ese punto, es posible que el cliente esté inmovilizado en la nueva máquina.
Las diferentes plataformas lo hacen de diferentes maneras, incluso sin tener ningún estado de sesión.
En ASP.NET puede persistir los datos de la sesión en una base de datos SQL Server que es común a todos los servidores web en el clúster.
Una vez configurado (en el sitio web.config para su sitio), el marco maneja toda la persistencia para usted y puede acceder a los datos de la sesión de forma normal.
Hay 3 formas de almacenar el estado de la sesión en ASP.NET. El primero está en proceso, donde las variables se almacenan en la memoria. El segundo es usar un servicio de estado de sesión poniendo lo siguiente en su archivo web.config:
<sessionState
mode="StateServer"
stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString="data source=127.0.0.1;user id=sa;password="
cookieless="false"
timeout="20" />
Como puede ver en el atributo stateConnectionString, el servicio de estado de la sesión puede ubicarse en una computadora diferente.
La tercera opción es usar una base de datos SQL centralizada. Para hacer eso, pones lo siguiente en tu web.config:
<sessionState
mode="SQLServer"
stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString=
"data source=SERVERHAME;user id=sa;password="
cookieless="false"
timeout="20"
/>
Más detalles sobre todas estas opciones se escriben aquí: http://www.ondotnet.com/pub/a/dotnet/2003/03/24/sessionstate.html
Obtenga una máquina Linux y configure http://www.danga.com/memcached . Su velocidad es inmejorable en comparación con otros enfoques. (por ejemplo, cookies, formar variables ocultas, bases de datos)
Para extender la respuesta de @ yogman.
¡Memcached es pura maravilla! Es un caché de objetos distribuidos y de alto rendimiento.
Y a pesar de que mencioné distribuido, es básicamente tan simple como comenzar una instancia en uno de sus servidores de repuesto / inactivos, usted lo configura como en ip, puerto y la cantidad de RAM que se utilizará y listo.
memcached -d -u www -m 2048 -l 10.0.0.8 -p 11211
(Ejecuta memcached en modo daemon, como usuario www, 2048 MB (2 GB) de RAM en IP 10.0.0.8 con puerto 11211).
A partir de ese momento, solicita datos de memcached y si los datos todavía no están en la memoria caché, los extrae de la fuente original y los almacena en memcached. Estoy seguro de que está familiarizado con los conceptos básicos de la caché.
En un entorno de clúster, puede vincular sus memcached en un clúster y replicar el caché en sus nodos. Memcached se ejecuta en Linux, Unix y Windows, inícielo en cualquier lugar donde tenga RAM libre y comience a utilizar sus recursos.
Las API para memcached deberían estar generalmente disponibles . Estoy diciendo que debería porque solo sé de Perl, Java y PHP. Pero estoy seguro de que, por ejemplo, en Python la gente también tiene medios para aprovecharla. Hay una wiki memcached , en caso de que necesite punteros, o hágamelo saber en los comentarios si estaba delirando demasiado. ;)
Con Hazelcast , puede usar el mapa distribuido de Hazelcast para almacenar y compartir sesiones en el clúster o permitir que Hazelcast Webapp Manager haga todo por usted. Por favor revisa los documentos para más detalles. Hazelcast es una solución de distribución de datos distribuida / particionada, superligera y sencilla, gratuita para Java.
Saludos,
-talip
Como dijo Will, la mayoría de los enfoques de balanceo de carga usarán algún tipo de rigidez en la forma en que distribuirán las próximas solicitudes del mismo cliente, es decir, un cliente único golpeará el mismo servidor a menos que el servidor real se caiga.
Eso minimiza la necesidad de distribución de datos de sesión, lo que significa que solo en caso de falla eventual de un servidor, un cliente perderá su sesión. Dependiendo de tu aplicación, esto es más o menos crítico. En la mayoría de los casos, esto no es un gran problema.
Incluso la forma más simple de carga de bala (redondear las búsquedas de DNS) hará cierta pegajosidad, ya que la mayoría de los navegadores guardarán en caché la búsqueda real y por lo tanto seguirán con el primer registro que recibieron, AFAIK.
Por lo general, el tiempo de ejecución es responsable de los datos de sesión, por ejemplo, PHP es posible definir tu propio controlador de sesión, que puede conservar los datos en una base de datos, por ejemplo. De forma predeterminada, PHP almacena los datos de sesión en los archivos, y es posible compartirlos en una SAN o equivalente para compartir datos de sesión. Esta era solo una teoría que tenía pero que nunca llegó a probar porque decidimos que perder sesiones no era crítico y no quería ese punto único de falla.
Para lograr el equilibrio de carga para ASP clásico , puede almacenar los valores específicos del usuario en la base de datos y pasar una identificación única de referencia en la URL de la siguiente manera.
Mantenga una tabla de sesión en la base de datos que genera una identificación única para cada registro. La primera vez que desee almacenar datos específicos de la sesión, genere un registro en su tabla de sesión y almacene los valores de la sesión en él. Obtenga la identificación única del nuevo registro de la sesión y vuelva a escribir todos los enlaces en su aplicación web para enviar la identificación única como parte de la cadena de consulta.
En cada página posterior en la que necesite los datos de la sesión, consulte la tabla de sesión con el ID único pasado en la cadena de consulta.
Ejemplo:
Considere que su sitio web tiene 4 páginas: Login.asp, welcome.asp, taskList.asp, newtask.asp
Cuando el usuario inicia sesión usando la página login.asp, después de validar al usuario, cree un registro en la tabla de sesión y almacene los valores específicos de la sesión requerida (digamos la fecha / hora de inicio de sesión del usuario para este ejemplo). Obtenga la identificación única del registro de la nueva sesión (digamos que la identificación única es abcd ).
Agregue todos los enlaces en su sitio web con el ID único de la siguiente manera:
- welcome.asp? sessionId = abcd
- tasklist.asp? sessionId = abcd
- newtask.asp? sessionId = abcd
Ahora, si en alguna de las páginas web anteriores desea mostrar la fecha / hora de inicio de sesión del usuario, solo tiene que consultar su tabla de sesión con el parámetro sessionID ( abcd en este caso) y mostrarle al usuario.
Dado que el valor único que identifica la sesión forma parte de la URL , cualquiera de los servidores web que brindan servicio al usuario podrá mostrar el valor correcto de fecha / hora de inicio de sesión.
Espero que esto ayude.