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:
- 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.
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
·
Manejo de sesiones. Disponible en:
http://www.juntadeandalucia.es/servicios/madeja/sites/default/files/historico/1.3.1/contenido-libro-pautas-65.html
·
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/
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.
ResponderEliminarHola Victor, disculpa que recién responda estuve desconectado estos días.
ResponderEliminarCon 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
Este comentario ha sido eliminado por el autor.
ResponderEliminarHola, 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?
ResponderEliminarPorque 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).