Ir al contenido principal

Configuración de Modo de estado de Sesión StateServer para aplicaciones ASP NET de alta disponibilidad

Hola a todos, el objetivo de este post es mostrar cómo se configura una aplicación para que soporte balanceo de carga y este alojado en una granja de servidores.  Con esto se quiere lograr que la aplicación sea de alta disponibilidad.

Se necesita que la sesión persista a pesar de que se redireccione al usuario hacia otro servidor (recordar que estamos con un balanceador en una granja de servidores) o se reinicie la aplicación.

Para esto en ASP .NET, ya sea web form o mvc la forma de poder manejar este caso es configurando el modo de estado de sesión fuera del proceso. ASP .NET tiene los siguientes modos de estado de sesión:
  • ·         Modo InProc, que almacena el estado de sesión en memoria en el servidor Web. Éste es el valor predeterminado.
  • ·         Modo StateServer, que almacena el estado de sesión en un proceso distinto denominado "servicio de estado de ASP.NET". Este modo garantiza que el estado de sesión se mantiene si se reinicia la aplicación Web y que esté disponible también para varios servidores Web en una batería de servidores Web.
  • ·         Modo SQLServer, que almacena el estado de sesión en una base de datos de SQL Server. Este modo garantiza que el estado de sesión se mantiene si se reinicia la aplicación Web y que esté disponible también para varios servidores Web en una batería de servidores Web.
  • ·         Modo Custom, que permite especificar un proveedor de almacenamiento personalizado.
  • ·         Modo Off, que deshabilita el estado de sesión.

Como pueden ver hay 3 modos que nos pueden servir para nuestro caso StateServer, SQLServer y Custom. Para esta ocasión mostraré un pequeño ejemplo de cómo configurar el modo de estado de sesión StateServer, pero antes primero veamos la siguiente imagen:




Como podemos ver en la imagen hay 3 servidores web donde estarán alojadas nuestra aplicación, un servidor web que se encargara de almacenar las sesiones de la aplicación y un balanceador de carga. Debería tener el siguiente comportamiento, si el balanceador redirecciona al usuario a los 3 servidores web donde está la aplicación, el usuario no debería iniciar sesión por cada servidor si no que bastará con que inicie sesión en un servidor para que este le comparta la sesión a los demás servidores (a través del servidor de sesiones), para el usuario debería ser transparente a que servidor lo envía el balanceador de carga. De igual manera si un servidor se cae debería mantenerse la sesión en los servidores restantes, esto ocurre ya que las sesiones se guardan en el servidor de sesiones (modo stateserver) al que tienen acceso las aplicaciones de todos los servidores web.
Para este ejemplo he creado una aplicación sencilla que guarda datos en una variable de sesión y luego la muestra en pantalla.
Ahora si sigamos los siguientes pasos para poder configurar el modo de estado de sesión a StateServer:

  1. Necesitamos que la aplicación desplegada en todos los servidores tenga el mismo nombre de appDomainAppId, para esto lo he tenido que hacer picando un poco de código para crear una función que se encargue de setear el nombre, esta función se llama  al iniciar la aplicación en el método de Application_Start del Global.asax

  2. Método que setea nombre de appDomainAppId applicationName).
Invocando al método.

2.  Desplegar la aplicación en los servidores correspondientes. En mi caso lo haré en el mismo servidor ya que no tengo a disposición una granja de servidores.



3. Generar un MachineKey (description and value) y ponerlo en el web.config de todas las aplicaciones desplegadas en los servidores, recordar que debe ser el mismo machineKey.
Esto es lo que va en el web.config:
<system.web> …….
<machineKey  decryptionKey="F0F788F2B888F6D0B26B2A0F7A8874B90376E22CA2684628" validationKey="CED98A316FB52EBD5FF90A7926E403EBDBE7282F71F02073F798C150152E7EB747636946A1F36F89DD1E829E17768069AA6F3D10C5F174DA0B75FCFFA6D861A6" />
…….</system.web>

Puedes generar el MachineKey desde el IIS:


4.  Agregar al web.config de todas las aplicaciones desplegadas la etiqueta sessionState, donde se indica el modo de estado de sesión a usar, cual es el servidor de sesiones y el timeout entre servidores:
<system.web> …….

<sessionState cookieName="StateServerApp" mode="StateServer" stateConnectionString="tcpip=TuServidorDeSesiones:42424" stateNetworkTimeout="40" />

…….</system.web>

5.  En el servidor de sesiones hay que iniciar el servicio Windows “ASP NET State Server” que es el encargado de manejar las sesiones.



Esto sería todo lo necesario para que nuestra aplicación este configurada con modo de estado de sesión StateServer en una granja de servidores con balanceador. Recuerda que este modo usa el puerto 42424 por lo tanto tiene que estar abierto.

El ejemplo lo puedes descargar del siguiente enlace: https://github.com/lrojasv/Ejemplo-State-Server/tree/master/EjemploStateServer

Aquí algunas imágenes del ejemplo funcionando:



Gracias.

Referencias bibliográficas:
·         Microsoft – Modos de Estado de Sesión. Disponible en: https://msdn.microsoft.com/es-es/library/ms178586(v=vs.100).aspx
·         Microsoft – Información general del estado de sesión ASP .Net. Disponible en: https://msdn.microsoft.com/es-es/library/ms178581(v=vs.100).aspx
·         Microsoft – Eventos de estado de sesión. Disponible en: https://msdn.microsoft.com/es-es/library/ms178583(v=vs.100).aspx
·         Microsoft – Proveedor de almacén de estados de sesión de ejemplo. Disponible en: https://msdn.microsoft.com/es-es/library/ms178588(v=vs.100).aspx
·         Microsoft – Elemento SessionState. Disponible en: https://msdn.microsoft.com/es-es/library/h6bb9cz9.aspx
·         Configurar SQL Server para almacenar el estado de la sesión de ASP.NET. Disponible en: http://devtroce.com/2011/02/22/configurar-sql-server-para-almacenar-el-estado-de-la-sesion-de-asp-net/ 


Comentarios

  1. Luis como estas, buen articulo, tengo una pregunta, actualmente donde trabajo hay una aplicación web desplegada en IIS 8.5, este servidor tiene Windows Server 2012 R2 como sistema operativo, bien queremos implementar un balanceo de carga. según entiendo debo tener otro servidor mas que sera una copia fiel del primero y luego otro servidor mas para implementar el State Server y otro mas para el balanceador, es así? hay alguna alternativa en donde use menos servidores?. Con respecto a la aplicación veo que hay que hacer cambios en la aplicación para ,manejar le session en el servidor State Server y cambiar también el web config de la aplicación, es esto totalmente necesario?, es decir hay forma de hacerlo sin modificar la aplicación?, gracias por tu respuesta.

    ResponderEliminar
  2. Hola Victor, disculpa que recién responda estuve desconectado estos días.
    Con respecto a tu preguntas:

    hay alguna alternativa en donde use menos servidores?
    Si, puedes usar menos servidores, puedes eliminar servidor de sesiones y ponerlo en uno de los servidores donde estará la aplicación, también eliminar el servidor de balanceo de carga y ponerlo en uno de los servidores donde estará la aplicación. La desventaja es que perderíamos la alta disponibilidad.
    Otra forma sería solo tener un servidor para la aplicación pero en el Application pool configurado el workerprocess > 1, con esto simularemos una granja de servidores y de esta forma no necesitarías el balanceador de carga.

    es decir hay forma de hacerlo sin modificar la aplicación?
    Si es necesario, de no hacerlo no podrán compartir sesiones las apps.

    Quisiera comentarte que la implementación de alta disponibilidad y balanceo de carga debe ser acorde a la demanda de la aplicación, si no es una aplicación crítica para el negocio y no es necesario asegurar disponibilidad 24/7 y la demanda no es alta, no veo la necesidad de implementarlo.

    Gracias

    ResponderEliminar
  3. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  4. Hola, tengo una pregunta, he llegado a la necesidad de tocar estos temas porque precisamente en una aplicación web tengo alta demanda de una API al punto que llegó al famoso código 503 HTTP de Service unavailable, lo solucioné precisamente utilizando los workprocess>1 (web garden), ahora tengo otro servidor con mismas capacidades y mi pregunta es, ¿es mejor utilizar el enfoque de web farm en lugar de web garden o relativamente los 2 enfoques te llevan al mismo resultado?

    Porque si me llevan al mismo resultado creo que sería mejor dejar 1 servidor exclusivo para la base de datos y en el otro servidor dejar la aplicación web con el enfoque de web garden (worker process>1).

    ResponderEliminar

Publicar un comentario

Entradas populares de este blog

Manejo de Caché en ASP NET MVC

Hola a todos, el objetivo de este post es aclarar ciertos puntos sobre el manejo de caché en ASP NET MVC. El manejo de la caché correctamente nos permite mejorar el rendimiento de nuestras aplicaciones, permitiéndonos almacenar información de uso frecuente y dentro de la memoria de alta velocidad. El manejo de la caché se puede dar tanto en el servidor como en el cliente. Este es un resumen de manejo de caché en ASP NET MVC: Page Output Caching: Es el manejo de caché a nivel de página o de acción en MVC. El navegador web puede almacenar en caché cualquier solicitud HTTP GET durante un periodo predefinido por lo que si el usuario solicita la misma URL, el navegador no llama al servidor, si no que carga la página desde la caché del navegador local. Te da la opción de decidir donde se va almacenar la página ya sea en el cliente o en el servidor. Solo se necesita decorar la acción con el atributo "OutputCache" e indicarle como se va a manejar: Duration (tiempo de durac

Inicio de sesión basado en tokens con Web Api

Hola a todos, el objetivo de este post será realizar el mecanismo de inicio de sesión basado en tokens para un servicio Rest Full con Web Api y Owin. Antes de empezar veamos un poco de teoría: Web Api:     Es un marco que facilita la creación de servicios HTTP disponibles para una amplia variedad de clientes, entre los que se incluyen exploradores y dispositivos móviles. ASP.NET Web API es la plataforma perfecta para crear aplicaciones RESTful en .NET Framework. Autenticación basada en Token: La forma preferida hoy en día para autenticarse desde el front-end ya sea web o mobile es la de tokens por las siguientes razones: Escalabilidad de servidores: El token que se envía al servidor es independiente, contiene toda la información necesaria para la autenticación del usuario, por lo que añadir más servidores a la granja es una tarea fácil ya que no depende de una sesión compartida. Bajo acoplamiento: Su aplicación front-end no se acopla con el mecanismo de autenticación