Dave Rendón Microsoft Azure MVP, embracing and fostering tech intensity to benefit society and thrive in a digital world.

Stateless App en Azure

6 min read

Configurar una virtual network site-to-site

En este artículo veremos por qué conviene y cómo diseñar una App stateless en Azure.

Una aplicación stateless (sin estado) es una aplicación que no registra datos generados en una sesión – como información acerca de la configuración de usuario y los eventos que ocurrieron para su uso en la próxima sesión con ese usuario. La tendencia hacia la nube está impulsando el interés en stateless Apps.

 

Crear aplicaciones por medio de worker roles en Azure son un ejemplo de los servicios ‘stateless’. Por el contrario, los microservicios con estado(stateful) mantienen el estado más allá de la solicitud y su respuesta, además de que proporcionan replicación a través de APIs sencillas. Los stateful services son la democratización de alta disponibilidad (HA) para todas las aplicaciones, no sólo las bases de datos y data storage. Esta es la evolución en el diseño, las aplicaciones han pasado de utilizar bases de datos puramente relacionales para HA, a bases de datos NoSQL y ahora a las propias aplicaciones que tengan estado gestionado dentro de ellas para los datos críticos que deben mantenerse actualizados.

Cuando construimos aplicaciones que consisten en microservicios, normalmente tienen una combinación de aplicaciones web stateless(ASP.NET, Node.js etc) que llaman a servicios stateless y stateful, todos desplegados en el mismo clúster del server fabric. La necesidad de la escalar, la confiabilidad y el uso de recursos para cada uno de estos microservicios proveen esta agilidad en el desarrollo y la gestión del ciclo de vida de la aplicación.

Los microservicios stateful simplifican los diseños de aplicaciones, ya que eliminan la necesidad de colas y cachés adicionales que tradicionalmente han sido necesarios para hacer frente a los requisitos de disponibilidad y de latencia de una aplicación. Los stateful service son enfocados hacia alta disponibilidad y baja latencia, lo cual significa menos movimiento de componentes para la gestión de la aplicación. Los siguientes diagramas ilustran las diferencias entre el diseño de una aplicación stateless VS una que es stateful. En el caso de servicios stateful, reducen la complejidad de la aplicación, mediante el logro de un alto rendimiento y baja latencia.

 

App construida con stateless services

appwithstatelessservices

App construida con stateful services

appwithstatefulservices

 

¿Cómo construir una App stateless?

El enfoque convencional para construir aplicaciones stateless es mover el estado  web/services fuera de la capa de la aplicación  ya sea en la configuración o en almacenamiento. Como se muestra en el diagrama a continuación, la solicitud de un usuario se dirige a través de la capa de la aplicación que puede referirse a la configuración para decidir el almacenamiento persistente (como, base de datos)para almacenar el estado. Por último, un servicio de la aplicación puede llevar a cabo la administración del estado.

wiki azure stateless

 

El Servicio de Utilidad App (en el diagrama anterior) realiza la carga de la gestión del estado. Se requiereel contexto de ejecución de App Tier de modo que puede desencadenar o bien una data-driven state machine o un event-drive state-machine. Un ejemplo de state machine para la gestión de errores tendría4 estados, como se muestra a continuación:

wiki azure bug

Para lograr esto en la aplicación, hay varias estrategias para gestionar el estado de la aplicación. Veamosalgunos de ellos.

 

Current State Event Action Next State
START NewBug OpenNew Bug Opened
Bug Opened Assigned AssignForFix Fix Needed
Not A Bug MarkClosed Bug Closed
Fix Needed Resolved MarkResolved Bug Fixed
ReOpened AssignForFix Fix Needed
Bug Fixed Tested MarkClosed Bug Closed
ReOpened MarkOpen Fix Needed
Bug Closed END

La estructura anterior define los estados finitos que una resolución de errors/bugs puede visitar. Cada acción tiene que ser consciente del contexto (es decir, la información de error mínimo y, a veces el state desde el que se invoca la acción) para que se pueda procesar de forma independiente el error y determinar el siguiente estado (especialmente cuando varios estados finales son posibles).

Cuando nos fijamos en la administración del estado de  la database-drive en Azure, podemos aprovechar una de estas soluciones

  • Azure SQL Database: La mejor opción cuando queremos trabajar con datos relacionales y estructurados utilizando las relaciones, índices, restricciones, etc. Se trata de una suite completa de base de datos MS-SQL alojado en Azure.
  • Azure Storage Tables: Funciona muy bien cuando queremos trabajar con datos estructurados y sin relaciones, posiblemente con volúmenes más grandes. Se observa una gran cantidad de veces mejor rendimiento a menor costo con tablas de almacenamiento especialmente cuando se utiliza para los datos sin relaciones. Leer más sobre este tema – SQL Azure y Microsoft Azure Storage Table por Joseph Fultz
  • DocumentDB: DocumentDB, una base de datos NoSQL, es una solución para almacenar datos no estructurados (schema-free) y pueden tener capacidades de consulta ricos a velocidades increíbles.A diferencia de otras bases de datos NoSQL, permite la creación de procedimientos almacenados y consulta con sentencias SQL. 
    Hay ocasiones en que podemos tener 2 peticiones que pueden escribir en la base de datos al mismo tiempo, lo cual puede ralentizar el rendimiento de nuestra aplicación. Existe la necesidad de un sistema de caché que nos prove de objetos de estado con velocidades de baja latencia pra solucionar este problema.

 

Manipulando la administración de estado con la caché

La persistencia de datos de estado utilizando un almacén de caché es también una excelente opción disponible para los desarrolladores. Los desarrolladores web han estado almacenando datos de estado (como, las preferencias del usuario, carritos de compra, etc.) en caché desde que se introdujo ASP.NET.De forma predeterminada, ASP.NET permite el almacenamiento de estado en memoria dentro del grupo de aplicaciones del hosting. En este caso se require almacenamiento de estado por las razones siguientes:
• La frecuencia con la que el proceso de trabajo de ASP.NET realiza el proceso de reciclaje está más allá del alcance de la aplicación y puede causar la caché en memoria sea borrada
• Con un balanceador de carga en la nube, no hay ninguna garantía de que el host que procesa la primera petición también recibirá la segunda. Así que hay posibilidades de que la información en la memoria en varios servidores puede no estar en sincronía

Otras alternativas a la gestión de memoria es ‘out-of-proc’ donde el estado es administrado ya sea por un servicio independiente o en el servidor SQL – algo que discutimos en la sección anterior. Este mecanismo asegura la flexibilidad y escalabilidad a costa de rendimiento. Por cada petición sea procesada, habrá de network call adicional para recuperar información de estado antes de procesar la solicitud, y otra network call para almacenar el nuevo estado.

La necesidad actual es tener un alto rendimiento, en memoria o servicio de caché distribuida para aprovechar la infraestructura Azure para actuar como un estado de baja latencia – como, Azure Redis caché.

Dentro de la aplicación, podemos tener un solo nodo o varios nodos (primario / secundario) de Redis caché para almacenar tipos de datos, como listas, hash, conjuntos ordenados y mapas de bits.

 

cache

Azure  Caché Redis soporta replicación master-slave con muy rápida sincronización y auto-reconexión.Así que, cuando elegimos-nodos múltiples para la gestión de caché Redis, estamos asegurando que nuestro estado de la aplicación no se gestiona en un solo servidor. Nuestro estado de la aplicación obtener replicado en varios nodos (es decir, esclavos) en tiempo real. También abre el nodo esclavo automáticamente cuando el nodo principal está desconectado.

Tolerancia a fallos con estrategias de gestión del Estado

Con la administración del estado con bases de datos y la gestión estatal caché impulsado, también tenemos que manejar las interrupciones temporales del servicio – posiblemente debido a las conexiones de red, capas de balanceadores de carga en la nube o algunos servicios de red troncal que estas soluciones utilizan. Para dar una experiencia transparente para nuestros usuarios finales, nuestro diseño de la aplicación debe manejar estos fallos transitorios.

Manejo de bases de datos errores transitorios

El uso de  Transient Fault Handling Application Block, con ADO.NET , podemos definir la política para volver a intentar la ejecución de comandos de base de datos y esperar periodo entre intentos para proporcionar una conexión fiable a la base de datos. O bien, si nuestra aplicación está utilizando cualquier versión de Entity Framework, podemos incluir SqlAzureExecutionStrategy, que configura la política para volver a intentar 3 veces con una espera exponencial entre intentos.

Cada reintento consume potencia de cálculo y ralentiza el rendimiento de las aplicaciones. Por lo tanto, debemos definir una política, un interruptor automático que evite la limitación del servicio mediante el procesamiento de las solicitudes con error.

Hay 2 maneras de implementar un interruptor automático para la administración del estado:


Fallback or Fail silent – Si hay un mecanismo de reserva para completar la funcionalidad solicitada sin la administración del estado, la aplicación debe intentar ejecutarlo. Por ejemplo, cuando la base de datos no está disponible, la aplicación puede que haga fallback del objeto de caché. Si no-fallback está disponible, nuestra aplicación puede fallar en silencio (es decir, obtener un void state para una solicitud).
• Fail fast – Error ante el usuario para evitar inundar el servicio de reintento y proporcionar una respuesta amigable para intentar más tarde.

Manejo de caché errores transitorios

Azure Caché Redis utiliza internamente ConnectionMultiplexer que reconecta automáticamente al caché Redis, debe haber interferencia desconexión o Internet. Sin embargo, el StackExchange.Redis no realiza retry para los commandos get y set. Para superar esta limitación, podemos utilizar la biblioteca como Polly que proporciona las políticas como en Retry, Retry Forever, Wait and Retry y Circuit Breaker de manera fluida.

Concluyendo…

Es clave diseñar aplicaciones teniendo en cuenta que la infraestructura en nube es flexible y que nuestras aplicaciones se deben diseñar para aprovechar sus beneficios sin comprometer la estabilidad y experiencia de usuario. Es sumamente importante para pensar en el almacenamiento de la información de la aplicación, sus mecanismos de acceso, manejo de excepciones y la demanda de la misma.

Fuentes y recomendaciones:

La versión en Inglés (escrito por Punit Ganshani) de este artículo fue publicada en Microsoft PressBlog:  Application Design: Going Stateless on Azure

* Stateless App

* Stateless

Dave Rendón Microsoft Azure MVP, embracing and fostering tech intensity to benefit society and thrive in a digital world.

Leave a Reply

Your email address will not be published. Required fields are marked *