Comunicación de cliente front-end

Sugerencia

Este contenido es un extracto del libro electrónico “Architecting Cloud Native .NET Applications for Azure” (Diseño de la arquitectura de aplicaciones .NET nativas en la nube para Azure), disponible en Documentos de .NET o como un PDF descargable y gratuito que se puede leer sin conexión.

Cloud Native .NET apps for Azure eBook cover thumbnail.

En un sistema nativo de nube, los clientes front-end (aplicaciones móviles, web y de escritorio) requieren un canal de comunicación para interactuar con microservicios back-end independientes.

¿Cuáles son las opciones?

Para simplificar las cosas, un cliente front-end podría comunicarse directamente con los microservicios back-end, como se muestra en la figura 4-2.

Direct client to service communication

Figura 4-2. Comunicación directa de cliente a servicio

Con este enfoque, cada microservicio tiene un punto de conexión público al que pueden acceder los clientes front-end. En un entorno de producción, colocaría un equilibrador de carga delante de los microservicios, enrutando el tráfico proporcionalmente.

Aunque es fácil de implementar, la comunicación de cliente directa solo sería aceptable para aplicaciones de microservicio simples. Este patrón acopla estrechamente los clientes front-end a los servicios back-end principales, lo que abre la puerta a muchos problemas, entre los que se incluyen:

  • Susceptibilidad del cliente a la refactorización del servicio back-end.
  • Una superficie de ataque más amplia, al exponerse directamente los servicios back-end principales.
  • Duplicación de problemas transversales entre cada microservicio.
  • Código de cliente demasiado complejo: los clientes deben realizar un seguimiento de varios puntos de conexión y manejar los errores de una manera resistente.

En su lugar, un patrón de diseño en la nube ampliamente aceptado es implementar un Servicio de puerta de enlace de API entre las aplicaciones front-end y los servicios back-end. El patrón se muestra en la figura 4-3.

API Gateway Pattern

Figura 4-3. Patrón de puerta de enlace de API

En la ilustración anterior, observe cómo el servicio de puerta de enlace de API abstrae los microservicios principales de back-end. Implementado como API web, actúa como proxy inverso y enruta el tráfico entrante a los microservicios internos.

La puerta de enlace aísla al cliente de la creación de particiones y refactorización del servicio interno. Si cambia un servicio back-end, puede acomodarlo en la puerta de enlace sin dar problemas al cliente. También es la primera línea de defensa para cuestiones transversales, como la identidad, el almacenamiento en caché, la resistencia, la medición y la limitación. Muchos de estas cuestiones transversales se pueden descargar de los servicios principales back-end a la puerta de enlace, lo que simplifica los servicios back-end.

Debe tener cuidado para que la puerta de enlace de API sea sencilla y rápida. Normalmente, la lógica de negocio se mantiene fuera de la puerta de enlace. Una puerta de enlace compleja corre el riesgo de convertirse en un cuello de botella y, finalmente, en un monolito. Los sistemas más grandes suelen exponer varias puertas de enlace de API segmentadas por tipo de cliente (móvil, web, escritorio) o funcionalidad back-end. El patrón Back-end para front-end proporciona la dirección para implementar varias puertas de enlace. El patrón se muestra en la figura 4-4.

Backend for Frontend Pattern

Figura 4-4. Patrón Back-end para front-end

Observe en la ilustración anterior cómo se envía el tráfico entrante a una puerta de enlace de API específica, en función del tipo de cliente: aplicación web, móvil o de escritorio. Este enfoque tiene sentido, ya que las funcionalidades de cada dispositivo difieren significativamente en función de las limitaciones de factor de forma, rendimiento y visualización. Normalmente, las aplicaciones móviles exponen menos funcionalidad que un explorador web o aplicaciones de escritorio. Cada puerta de enlace se puede optimizar para que coincida con las capacidades y funcionalidades del dispositivo correspondiente.

Puertas de enlace sencillas

Para empezar, puede crear su propio servicio de puerta de enlace de API. Una búsqueda rápida de GitHub proporcionará muchos ejemplos.

En el caso de aplicaciones sencillas nativas de nube de .NET, puede considerar la puerta de enlace de Ocelot. De código abierto y creado para microservicios de .NET, es ligera, rápida y escalable. Al igual que cualquier puerta de enlace de API, su funcionalidad principal es reenviar las solicitudes HTTP entrantes a los servicios de nivel inferior. Además, admite una amplia variedad de funcionalidades que se pueden configurar en una canalización de middleware de .NET.

YARP (Otro Proxy Inverso) es otro proxy inverso de código abierto dirigido por un grupo de equipos de productos de Microsoft. Descargable como un paquete NuGet, YARP se conecta al marco ASP.NET como middleware y es muy personalizable. Encontrará YARP bien documentado con varios ejemplos de uso.

En el caso de las aplicaciones nativas de nube empresariales, hay varios servicios administrados de Azure que pueden ayudar a empezar a trabajar.

Azure Application Gateway

En el caso de los requisitos de puerta de enlace simples, puede considerar Azure Application Gateway. Disponible como un servicio PaaS de Azure, incluye características básicas de puerta de enlace, como el enrutamiento de direcciones URL, la terminación SSL y un Web Application Firewall. El servicio admite funcionalidades de equilibrio de carga de capa 7. Con capa 7 puede enrutar las solicitudes en función del contenido real de un mensaje HTTP, no solo de los paquetes de red TCP de bajo nivel.

En este libro evangelizamos sobre el hospedaje de sistemas nativos de nube en Kubernetes. Kubernetes, un orquestador de contenedores, automatiza la implementación, el escalado y las cuestiones operativas de las cargas de trabajo contenedorizadas. Azure Application Gateway se puede configurar como puerta de enlace de API para un clúster de Azure Kubernetes Service.

El Controlador de entrada de Application Gateway permite que Azure Application Gateway funcione directamente con Azure Kubernetes Service. En la figura 4.5 se muestra la arquitectura.

Application Gateway Ingress Controller

Figura 4-5. Controlador de entrada de Application Gateway

Kubernetes incluye una característica integrada que admite el equilibrio de carga HTTP (nivel 7), denominada Ingress. Ingress define un conjunto de reglas para la forma en que las instancias de microservicio dentro de AKS se pueden exponer al mundo exterior. En la imagen anterior, el controlador de entrada interpreta las reglas de entrada configuradas para el clúster y configura automáticamente la Azure Application Gateway. En función de esas reglas, la Application Gateway enruta el tráfico a los microservicios que se ejecutan dentro de AKS. El controlador de entrada escucha los cambios en las reglas de entrada y realiza los cambios adecuados en la Azure Application Gateway.

Azure API Management

Para sistemas nativos de nube de gran escala a moderados, puede tener en cuenta Azure API Management. Se trata de un servicio basado en la nube que no solo resuelve las necesidades de la puerta de enlace de API, sino que proporciona una experiencia completa de desarrollador y administrador. API Management se muestra en la figura 4-6.

Azure API Management

Figura 4-6. Azure API Management

Para empezar, API Management expone un servidor de puerta de enlace que permite el acceso controlado a los servicios back-end en función de reglas y directivas configurables. Estos servicios pueden estar en la nube de Azure, en el centro de datos locales o en otras nubes públicas. Las claves de API y los tokens JWT determinan quién puede hacer qué. Todo el tráfico se registra con fines analíticos.

Para desarrolladores, API Management ofrece un portal para desarrolladores que proporciona acceso a servicios, documentación y código de ejemplo para invocarlos. Los desarrolladores pueden usar Swagger/Open API para inspeccionar los puntos de conexión de servicio y analizar su uso. El servicio funciona entre las principales plataformas de desarrollo: .NET, Java, Golang, etc.

El portal del publicador expone un panel de administración donde los administradores exponen las API y administran su comportamiento. Se puede conceder acceso al servicio, supervisar el estado del servicio y recopilar la telemetría del servicio. Los administradores aplican directivas a cada punto de conexión para afectar al comportamiento. Las directivas son instrucciones precompiladas que se ejecutan secuencialmente para cada llamada de servicio. Las directivas se configuran para una llamada entrante, una llamada saliente o se invocan en caso de error. Las directivas se pueden aplicar en distintos ámbitos de servicio, así como para habilitar la ordenación determinista al combinar directivas. El producto se distribuye con un gran número de directivas precompiladas.

Estos son ejemplos de cómo pueden afectar las directivas al comportamiento de los servicios nativos de nube:

  • Restringir el acceso al servicio.
  • Exigir autenticación.
  • Limitar las llamadas desde un único origen, si es necesario.
  • Activación del almacenamiento en caché.
  • Bloquear llamadas desde direcciones IP específicas.
  • Controlar el flujo del servicio.
  • Convertir solicitudes de SOAP a REST o entre diferentes formatos de datos, como de XML a JSON.

Azure API Management puede exponer servicios back-end hospedados en cualquier lugar, en la nube o en el centro de datos. En el caso de los servicios heredados que puede exponer en los sistemas nativos de la nube, admite las API de REST y de SOAP. Incluso otros servicios de Azure se pueden exponer mediante API Management. Podría colocar una API administrada sobre un servicio de respaldo de Azure, como Azure Service Bus o Azure Logic Apps. Azure API Management no incluye compatibilidad integrada con el equilibrio de carga y debe usarse junto con un servicio de equilibrio de carga.

Azure API Management está disponible en cuatro niveles de servicio diferentes:

  • Desarrollador
  • Basic
  • Estándar
  • Premium

El nivel Desarrollador está pensado para cargas de trabajo y evaluación que no son de producción. Los demás niveles ofrecen cada vez más potencia, características y contratos de nivel de servicio (SLA) superiores. El nivel Premium proporciona compatibilidad con Azure Virtual Network y varias regiones. Todos los niveles tienen un precio fijo por hora.

La nube de Azure también ofrece un nivel sin servidor para Azure API Management. Conocido como plan de tarifa de consumo, el servicio es una variante de API Management diseñada en torno al modelo de informática sin servidor. A diferencia de los planes de tarifa "asignados previamente" mostrados anteriormente, el nivel de consumo proporciona precios instantáneos de aprovisionamiento y pago por acción.

Habilita las características de puerta de enlace de API para los siguientes casos de uso:

  • Microservicios implementados mediante tecnologías sin servidor, como Azure Functions y Azure Logic Apps.
  • Recursos del servicio de respaldo de Azure, como colas de Service Bus y temas, Azure Storage, etc.
  • Microservicios en los que el tráfico tiene picos grandes ocasionales, pero sigue siendo bajo la mayor parte del tiempo.

El nivel de consumo usa el mismo servicio subyacente de componentes de API Management, pero emplea una arquitectura completamente diferente basada en recursos asignados dinámicamente. Se alinea perfectamente con el modelo de informática sin servidor:

  • No hay que administrar ninguna infraestructura.
  • No hay capacidad inactiva.
  • Alta disponibilidad.
  • Escalado automático
  • El coste se basa en el uso real.

El nuevo nivel de consumo es una excelente opción para los sistemas nativos de nube que exponen recursos sin servidor como API.

Comunicación en tiempo real

La comunicación en tiempo real o de inserción es otra opción para las aplicaciones front-end que se comunican con sistemas back-end nativos de nube a través de HTTP. Las aplicaciones, como los teletipos financieros, la educación en línea, los juegos y las actualizaciones de progreso del trabajo, requieren respuestas instantáneas en tiempo real del back-end. Con la comunicación HTTP normal, no hay ninguna manera de que el cliente sepa cuándo hay nuevos datos disponibles. El cliente debe sondear o enviar continuamente solicitudes al servidor. Con la comunicación en tiempo real, el servidor puede insertar nuevos datos al cliente en cualquier momento.

Los sistemas en tiempo real suelen caracterizarse por flujos de datos de alta frecuencia y un gran número de conexiones de cliente simultáneas. La implementación manual de la conectividad en tiempo real puede convertirse rápidamente en compleja, al requerir una infraestructura no despreciable para garantizar la escalabilidad y una mensajería confiable a los clientes conectados. Podría encontrarse administrando una instancia de Azure Redis Cache y un conjunto de equilibradores de carga configurados con sesiones permanentes para la afinidad de cliente.

Azure SignalR Service es un servicio de Azure totalmente administrado que simplifica la comunicación en tiempo real para las aplicaciones nativas de la nube. Los detalles de implementación técnica, como el aprovisionamiento de capacidad, el escalado y las conexiones persistentes, se abstrae. Se administran por usted con un contrato de nivel de servicio del 99,9 %. Usted se centra en las características de la aplicación, no en la canalización de la infraestructura.

Una vez habilitado, un servicio HTTP basado en la nube puede insertar actualizaciones de contenido directamente a los clientes conectados, incluidas las aplicaciones de explorador, móviles y de escritorio. Los clientes se actualizan sin necesidad de sondear el servidor. Azure SignalR abstrae las tecnologías de transporte que crean conectividad en tiempo real, incluidos WebSockets, Server-Side Events y Long Polling. Los desarrolladores se centran en enviar mensajes a todos los subconjuntos o a subconjuntos específicos de clientes conectados.

En la figura 4-7 se muestra un conjunto de clientes HTTP que se conectan a una aplicación nativa de nube con Azure SignalR habilitado.

Azure SignalR

Figura 4-7. Azure SignalR

Otra ventaja de Azure SignalR Service aparece con la implementación de servicios nativos de nube sin servidor. Quizás el código se ejecute bajo demanda con desencadenadores de Azure Functions. Este escenario puede ser complicado porque el código no mantiene conexiones largas con los clientes. Azure SignalR Service puede encargarse de esta situación, ya que el servicio ya administra las conexiones por usted.

Azure SignalR Service se integra estrechamente con otros servicios de Azure, como Azure SQL Database, Service Bus o Redis Cache, lo que abre muchas posibilidades para las aplicaciones nativas de nube.