martes, 2 de abril de 2019

Variables de Sesión y Cookies en Ambientes Multiservidor con LoadBalancer.

A los loadbalancers no le gustan las variables de sesión almacenadadas en servidor. Prefieren las cookies.

Primero, clarifiquemos cada componente.

Un LoadBalancer es un componente de la red que distribuye el tráfico hacia uno u otro servidor -de un grupo de servidores declarados- dependiendo de alguna regla. Esta regla puede ser el tiempo de duración de un servidor en responder o la cantidad de peticiones que esta atendiendo cada servidor del grupo.

Una Variable de Sesión Almacenada en Servidor, es un dato que se maneja dentro de un servidor, vinculada a la computadora que inició la petición mediante un dato llamado "cookie_id". Mediante este dato "cookie_id" buscará el dato requerido dentro del servidor y podrá saber qué dato le corresponde a cada visitante.

Una Cookie, es un archivo de texto almacenado en el computador que inició la petición -no en el servidor- y se guardará allí un dato que será enviado al servidor que sirva la petición, usando el encabezado del paquete http.

Estas tres cosas son clave a la hora de fabricar software capaz de escalar para poder atender alto tráfico.

Cómo funcionan estos componentes en un escenario real.

Supongamos que hemos creado un servicio web, que se ejecuta en una UrL específica, que leerá un numero de la base de datos, nada mas, algo simple. Pero, este servicio será invocado simultáneamente 100.000 veces. Cuando digo "simultáneo" significa que a la vez hay 100.000 peticiones ejecutándose en el mismo "momentum".

Este simple hecho puede colapsar tanto al servidor como al motor de datos. Sobre todo al servidor http si el software no esta bien diseñado. Me enfocaré en el servidor, debido a que el framework web que se usa para fabricar al servicio tendrá con seguridad una reutilización de la conexión de la base de datos, de modo de no generar 100.000 conexiones, sino solo una.

Muy probablemente el servidor se caerá con este gran número de conexiones. Sí, nodejs puede con eso y mas, pero entonces, para nodejs hablemos de 100.000.000 de conexiones y también se caerá. Queremos hacer un cluster, donde cada nodo (servidor) sea capaz de atender un numero decente de peticiones. Supongamos que estamos forzados a usar un servidor apache.

Cuando el navegador u otro servicio requiere al servicio web que describo acá, entonces la URL los llevará al Loadbalancer y no a un servidor específico. El LoadBalancer seleccionará un servidor, utilizando alguna regla.  En AmazonAWS, el loadbalancer es tan excelente que es capaz de levantar un servidor desde una imagen de disco, echándolo a andar y conectándolo al Loadbalancer, luego, cuando la demanda baje entonces será capaz de eliminar el servidor para reducir costes.

Supongamos que hemos creado dos servidores sirviendo el mismo código fuente. Cada servidor atiende peticiones en "http://servidor-1/servicio" y "http://servidor-2/servicio", siendo "servicio" el codigo que devuelve un dato necesario. Cada servidor usa el mismo codigo, cada uno es un clon del otro, cuya unica diferencia es la IP y su MAC por supuesto.

El loadbalancer elegirá al servidor1 o el servidor2, por tanto, todo lo que el navegador envió originalmente a "https://www.prueba.cl/servicio" irá a parar a uno de los dos servidores declarados en el Loadbalancer.  Note que he puesto "https", el loadbalancer puede recibir contenido seguro y mapearlo a "http" -no seguro- en cada instancia declarada, sin perder la seguridad, porque se supone que hay una red privada entre servidor1, servidor2 y el loadbalancer, nadie interfiere allí.

El servidor1 o el servidor2 atenderá la petición, hace su trabajo y devuelve un dato. Para el navegador no hubo diferencia. De este modo tenemos un pequeño cluster de dos servidores que atienden peticiones como si de uno solo se tratase.

Es seguro. No hay puertos extraños abiertos, nadie puede acceder a los servidores que estan declarados en el loadbalancer.

Ahora, veamos el problema de los datos de sesión del usuario. Supongamos que la petición depende de algún dato introducido por el usuario, digamos su RUT o CEDULA. Este dato se puede almacenar en una cookie o en una variable de servidor, pero, dependiendo de si usamos o no a un loadbalancer entonces un método prevalecerá y el otro no podrá usarse.

Memoria de Sesión: via cookies o variables de sesión en el lado del servidor. ?

Dependerá de cómo estamos instalando nuestros servicios, con o sin loadbalancers.

Cuando NO hay loadbalancer y solo UNA instancia -servidor- atiende a todas las peticiones entonces se puede usar una "memoria de sesión" de tipo "variable de sesión". Debido a que el dato clave estará en el lado del servidor final y no hay necesidad de compartirlo con otros servidores -porque solo hay uno-.

Cuando HAY un loadbalancer y MAS DE UNA instancia sirve las peticiones -digamos que hay 2 servidores- entonces el uso de variables de sesión echará todo por tierra porque el dato que el usuario necesita se habrá quedado en un servidor y los demas servidores no lo conocerán. Para este caso vienen las cookies al rescate.

Las cookies. Debido a la naturaleza de las cookies -almacenar datos en el computador/teléfono que inició la llamada- entonces, cada vez que la petición llega al loadbalancer se copiarán las "cookies" que provienen de ella hacia la instancia que toque servir a la petición.  Por tanto, el servidor1 y el servidor2 recibirán la misma cookie siempre y por consecuencia el dato necesario para servir, digamos el RUT o CEDULA.

Ejemplo


Supongamos que tenemos un sistema de manejo de usuarios (login/logout) y este sistema es atendido por un loadbalancer con 10 servidores detrás, para atender una situación pesada de 100.000 visitantes que quieren registrarse a la vez.

Si usamos "memoria de sesion" del tipo "variables del servidor" entonces todo fallará, porque el usuario se registrará y su "USER_ID" quedará grabado en el primer servidor que le atendió (podría ser cualquiera del uno al diez). Cuando el usuario se termine de registrar y quiera hacer login se dará cuenta que a veces podrá iniciar sesión y a veces no, dependerá de que si con suerte le ha tocado todo el tiempo el mismo servidor, y eso no ocurrirá, porque el Loadbalancer no siempre dará al mismo servidor.

Si usamos "memoria de sesión" del tipo "cookies", entonces su USER_ID se guardará en su computador y no importará a cual servidor se le delegue la petición; el sistema siempre conocerá su USER_ID porque el Loadbalancer lo tomó de la petición que el navegador le hizo y se lo copió al servidor seleccionado. Por tanto, cualquiera de los 10 servidores declarados sabrá qué usuario esta solicitando el servicio.

Resúmen

Si la aplicación web o el servicio web correrá solo en un servidor entonces da igual si se usan cookies o memoria de servidor.  Si se usan multiples servidores conectados por un loadbalancer entonces se deben usar cookies.