Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Sugerencia
Este contenido es un extracto del libro electrónico, ".NET Microservices Architecture for Containerized .NET Applications" (Arquitectura de microservicios de .NET para aplicaciones de .NET contenedorizadas), disponible en Documentación de .NET o como un PDF descargable y gratuito que se puede leer sin conexión.
En una arquitectura de microservicios, cada microservicio expone un conjunto de puntos de conexión específicos (normalmente). Este hecho puede afectar a la comunicación de cliente a microservicio, como se explica en esta sección.
Comunicación directa de cliente a microservicio
Un posible enfoque es usar una arquitectura de comunicación de cliente a microservicio directa. En este enfoque, una aplicación cliente puede realizar solicitudes directamente a algunos de los microservicios, como se muestra en la figura 4-12.
Figura 4-12. Uso de una arquitectura de comunicación de cliente a microservicio directa
En este enfoque, cada microservicio tiene un punto de conexión público, a veces con un puerto TCP diferente para cada microservicio. Un ejemplo de una dirección URL para un servicio determinado podría ser la siguiente dirección URL en Azure:
http://eshoponcontainers.westus.cloudapp.azure.com:88/
En un entorno de producción basado en un clúster, esa dirección URL se asignaría al equilibrador de carga usado en el clúster, que a su vez distribuye las solicitudes entre los microservicios. En entornos de producción, podría tener un controlador de entrega de aplicaciones (ADC) como Azure Application Gateway entre los microservicios e Internet. Esta capa actúa como un nivel transparente que no solo realiza el equilibrio de carga, sino que protege los servicios ofreciendo terminación SSL. Este enfoque mejora la carga de los servidores al transferir la terminación SSL intensiva de CPU y otras funciones de enrutamiento al Azure Application Gateway. En cualquier caso, un equilibrador de carga y ADC son transparentes desde un punto de vista de arquitectura de aplicación lógica.
Una arquitectura de comunicación de cliente a microservicio directa podría ser suficiente para una pequeña aplicación basada en microservicios, especialmente si la aplicación cliente es una aplicación web del lado servidor como una aplicación ASP.NET MVC. Sin embargo, al construir aplicaciones grandes y complejas basadas en microservicios (por ejemplo, al gestionar docenas de tipos de microservicios), y especialmente cuando las aplicaciones cliente son aplicaciones móviles remotas o aplicaciones web SPA, este enfoque enfrenta ciertos problemas.
Tenga en cuenta las siguientes preguntas al desarrollar una aplicación grande basada en microservicios:
- ¿Cómo pueden las aplicaciones cliente minimizar el número de solicitudes al back-end y reducir la comunicación chatty a varios microservicios?
La interacción con varios microservicios para crear una sola pantalla de interfaz de usuario aumenta el número de recorridos de ida y vuelta a través de Internet. Este enfoque aumenta la latencia y la complejidad en la interfaz de usuario. Idealmente, las respuestas deben agregarse eficazmente en el lado servidor. Este enfoque reduce la latencia, ya que varios fragmentos de datos vuelven en paralelo y algunas interfaces de usuario pueden mostrar los datos tan pronto como esté listo.
- ¿Cómo puede controlar los problemas transversales, como la autorización, las transformaciones de datos y el envío dinámico de solicitudes?
La implementación de problemas de seguridad y transversales, como la seguridad y la autorización en cada microservicio, pueden requerir un esfuerzo de desarrollo significativo. Un posible enfoque consiste en tener esos servicios dentro del host de Docker o en el clúster interno para restringir el acceso directo a ellos desde el exterior e implementar esos problemas transversales en un lugar centralizado, como una puerta de enlace de API.
- ¿Cómo se pueden comunicar las aplicaciones cliente con servicios que usan protocolos que no son compatibles con Internet?
Los protocolos usados en el lado servidor (como AMQP o protocolos binarios) no se admiten en las aplicaciones cliente. Por lo tanto, las solicitudes deben realizarse a través de protocolos como HTTP/HTTPS y traducirse a los demás protocolos después. Un enfoque man-in-the-middle puede ayudar en esta situación.
- ¿Cómo puede dar forma a una fachada especialmente hecha para aplicaciones móviles?
Es posible que la API de varios microservicios no esté bien diseñada para las necesidades de diferentes aplicaciones cliente. Por ejemplo, las necesidades de una aplicación móvil pueden ser diferentes de las necesidades de una aplicación web. En el caso de las aplicaciones móviles, es posible que tenga que optimizar aún más para que las respuestas de datos puedan ser más eficaces. Puede realizar esta funcionalidad agregando datos de varios microservicios y devolviendo un único conjunto de datos y, a veces, eliminando los datos de la respuesta que no necesita la aplicación móvil. Y, por supuesto, podría comprimir esos datos. De nuevo, una fachada o una API entre la aplicación móvil y los microservicios pueden ser convenientes para este escenario.
Por qué considerar las puertas de enlace de API en lugar de la comunicación directa de cliente a microservicio
En una arquitectura de microservicios, las aplicaciones cliente suelen necesitar consumir funcionalidad de más de un microservicio. Si ese consumo se realiza directamente, el cliente debe controlar varias llamadas a los puntos de conexión de microservicios. ¿Qué ocurre cuando la aplicación evoluciona y se introducen nuevos microservicios o se actualizan los microservicios existentes? Si la aplicación tiene muchos microservicios, controlar tantos puntos de conexión de las aplicaciones cliente pueden ser una pesadilla. Dado que la aplicación cliente se acoplaría a esos puntos de conexión internos, la evolución de los microservicios en el futuro puede provocar un gran impacto para las aplicaciones cliente.
Por lo tanto, tener un nivel intermedio o nivel de direccionamiento indirecto (puerta de enlace) puede ser cómodo para las aplicaciones basadas en microservicios. Si no tiene puertas de enlace de API, las aplicaciones cliente deben enviar solicitudes directamente a los microservicios y que generen problemas, como los siguientes:
Acoplamiento: sin el patrón de puerta de enlace de API, las aplicaciones cliente se acoplan a los microservicios internos. Las aplicaciones cliente deben saber cómo se descompone varias áreas de la aplicación en microservicios. Al evolucionar y refactorizar los microservicios internos, esas acciones afectan al mantenimiento porque provocan cambios importantes en las aplicaciones cliente debido a la referencia directa a los microservicios internos de las aplicaciones cliente. Las aplicaciones cliente deben actualizarse con frecuencia, lo que dificulta la evolución de la solución.
Demasiados recorridos de ida y vuelta: una sola página o pantalla en la aplicación cliente puede requerir varias llamadas a varios servicios. Este enfoque puede dar lugar a varios recorridos de ida y vuelta de red entre el cliente y el servidor, lo que agrega una latencia significativa. La agregación controlada en un nivel intermedio podría mejorar el rendimiento y la experiencia del usuario para la aplicación cliente.
Problemas de seguridad: sin una puerta de enlace, todos los microservicios deben exponerse al "mundo externo", haciendo que la superficie expuesta a ataques sea mayor que si oculta microservicios internos que las aplicaciones cliente no usan directamente. Cuanto menor sea la superficie expuesta a ataques, más segura puede ser la aplicación.
Problemas transversales: cada microservicio publicado públicamente debe controlar cuestiones como la autorización y SSL. En muchas situaciones, esas preocupaciones se podrían controlar en un solo nivel para que los microservicios internos se simplificaran.
¿Cuál es el patrón de puerta de enlace de API?
Al diseñar y construir aplicaciones grandes o complejas basadas en microservicios con múltiples aplicaciones cliente, se puede considerar un buen enfoque como el API Gateway. Este patrón es un servicio que proporciona un punto de entrada único para determinados grupos de microservicios. Es similar al patrón de fachada del diseño orientado a objetos, pero en este caso, forma parte de un sistema distribuido. En ocasiones, el patrón de puerta de enlace de API también se conoce como "back-end para front-end" (BFF) porque en la compilación se tienen en cuenta las necesidades de la aplicación cliente.
Por lo tanto, la puerta de enlace de API se encuentra entre las aplicaciones cliente y los microservicios. Funciona como proxy inverso, enrutando las solicitudes de los clientes a los servicios. También puede proporcionar otras características transversales, como la autenticación, la terminación SSL y la memoria caché.
En la figura 4-13 se muestra cómo una puerta de enlace de API personalizada puede caber en una arquitectura simplificada basada en microservicios con solo unos pocos microservicios.
Figura 4-13. Uso de una puerta de enlace de API implementada como un servicio personalizado
Las aplicaciones se conectan a un único punto de conexión, la puerta de enlace de API, que está configurada para reenviar solicitudes a microservicios individuales. En este ejemplo, la puerta de enlace de API se implementaría como un servicio WebHost de ASP.NET core personalizado que se ejecuta como un contenedor.
Es importante resaltar que, en ese diagrama, usaría un único servicio de puerta de enlace de API personalizada que sirve a varias y diversas aplicaciones cliente. Ese hecho puede ser un riesgo importante porque el servicio API Gateway va a crecer y evolucionar en función de muchos requisitos diferentes de las aplicaciones cliente. Finalmente, se sobredimensionará debido a esas necesidades diferentes y, de hecho, podría ser similar a una aplicación monolítica o servicio monolítico. Por eso es muy recomendable dividir la puerta de enlace de API en varios servicios o varias puertas de enlace de API más pequeñas, una por tipo de factor de forma de aplicación cliente, por ejemplo.
Debe tener cuidado al implementar el patrón de puerta de enlace de API. Normalmente, no es una buena idea tener una sola puerta de enlace de API que agregue todos los microservicios internos de tu aplicación. Si lo hace, actúa como agregador monolítico o orquestador y infringe la autonomía del microservicio mediante el acoplamiento de todos los microservicios.
Por lo tanto, las puertas de enlace de API se deben separar en función de los límites empresariales y las aplicaciones cliente y no actuar como un único agregador para todos los microservicios internos.
Al dividir el nivel de API Gateway en varias puertas de enlace de API, si su aplicación tiene varias aplicaciones cliente, puede servir como un punto clave para identificar los diferentes tipos de puertas de enlace de API, permitiéndole tener diferentes fachadas según las necesidades de cada aplicación cliente. Este caso es un patrón denominado "back-end para front-end" (BFF), donde cada puerta de enlace de API puede proporcionar una API distinta adaptada a cada tipo de aplicación cliente, posiblemente basada incluso en el factor de forma de cliente, mediante la implementación de código adaptador específico que llame, de forma subyacente, a varios servicios internos, como se muestra en la imagen siguiente:
Figura 4-13.1. Uso de varias puertas de enlace de API personalizadas
En la figura 4-13.1 se muestran las puertas de enlace de API segregadas por tipo de cliente; uno para clientes móviles y otro para clientes web. Una aplicación web tradicional se conecta a un microservicio MVC que usa la puerta de enlace de API web. En el ejemplo se muestra una arquitectura simplificada con varias puertas de enlace de API específicas. En este caso, los límites identificados para cada puerta de enlace de API se basan exclusivamente en el patrón "Back-end para front-end" (BFF), por lo que se basa solo en la API necesaria por aplicación cliente. Sin embargo, en aplicaciones más grandes, también debe ir más allá y crear otras puertas de enlace de API basadas en los límites del negocio como un segundo eje de diseño.
Características principales del patrón de puerta de enlace de API
Una puerta de enlace de API puede ofrecer varias características. En función del producto, puede ofrecer características más enriquecidas o más sencillas, pero las características más importantes y fundamentales de cualquier puerta de enlace de API son los siguientes patrones de diseño:
Proxy inverso o enrutamiento de puerta de enlace. La puerta de enlace de API ofrece un proxy inverso para redirigir o enrutar solicitudes (enrutamiento de nivel 7, normalmente solicitudes HTTP) a los puntos de conexión de los microservicios internos. La puerta de enlace proporciona un único punto de conexión o una dirección URL para las aplicaciones cliente y, a continuación, asigna internamente las solicitudes a un grupo de microservicios internos. Esta característica de enrutamiento ayuda a desconectar las aplicaciones cliente de los microservicios, pero también resulta práctica al modernizar una API monolítica colocando la puerta de enlace de API entre la API monolítica y las aplicaciones cliente; de este modo, se pueden agregar nuevas API como nuevos microservicios mientras se sigue usando la API monolítica heredada hasta que se divida en muchos microservicios en el futuro. Debido a la puerta de enlace de API, las aplicaciones cliente no observarán si las API que se usan se implementan como microservicios internos o una API monolítica y, lo que es más importante, al evolucionar y refactorizar la API monolítica en microservicios, gracias al enrutamiento de la puerta de enlace de API, las aplicaciones cliente no se verán afectadas con ningún cambio de URI.
Para obtener más información, consulte Patrón Gateway Routing.
Agregación de solicitudes. Como parte del patrón de puerta de enlace, puede agregar varias solicitudes de cliente (normalmente solicitudes HTTP) destinadas a varios microservicios internos en una sola solicitud de cliente. Este patrón es especialmente conveniente cuando una página o pantalla de cliente necesita información de varios microservicios. Con este enfoque, la aplicación cliente envía una única solicitud a la puerta de enlace de API que envía varias solicitudes a los microservicios internos y, a continuación, agrega los resultados y devuelve todo a la aplicación cliente. La principal ventaja y el objetivo de este patrón de diseño es reducir el chateo entre las aplicaciones cliente y la API de backend, lo cual es especialmente importante para las aplicaciones remotas fuera del centro de datos donde residen los microservicios, como las aplicaciones móviles o las solicitudes provenientes de aplicaciones SPA que se originan en JavaScript en navegadores remotos del cliente. Para las aplicaciones web normales que realizan las solicitudes en el entorno de servidor (como una aplicación web MVC de ASP.NET Core), este patrón no es tan importante, ya que la latencia es mucho menor que para las aplicaciones cliente remotas.
En función del producto de puerta de enlace de API que use, es posible que pueda realizar esta agregación. Sin embargo, en muchos casos es más flexible crear microservicios de agregación en el ámbito de la puerta de enlace de API, por lo que se define la agregación en el código (es decir, código de C#):
Para obtener más información, consulte Patrón de agregación de Gateway.
Cuestiones transversales o descarga de puerta de enlace. En función de las características que ofrece cada producto de puerta de enlace de API, puede descargar la funcionalidad de microservicios individuales a la puerta de enlace, lo que simplifica la implementación de cada microservicio mediante la consolidación de preocupaciones transversales en un nivel. Este enfoque es especialmente conveniente para las características especializadas que pueden ser complejas de implementar correctamente en cada microservicio interno, como la siguiente funcionalidad:
- Autenticación y autorización
- Integración de la detección de servicios
- Almacenamiento en caché de respuesta
- Directivas de reintento, cortacircuitos, y Calidad de Servicio (QoS)
- Limitación de velocidad
- Equilibrio de carga
- Registro, seguimiento, correlación
- Encabezados, cadenas de consulta y transformación de notificaciones
- Adición a la lista de direcciones IP permitidas
Para obtener más información, consulte Patrón Gateway Offloading.
Uso de productos con características de API Gateway
Puede haber muchos más problemas transversales ofrecidos por los productos de puertas de enlace de API en función de cada implementación. Exploraremos aquí:
Azure API Management
Azure API Management (como se muestra en la figura 4-14) no solo resuelve las necesidades de la puerta de enlace de API, sino que proporciona características como recopilar información de las API. Si usa una solución de API Management, una puerta de enlace de API solo es un componente dentro de esa solución completa de API Management.
Figura 4-14. Uso de Azure API Management para la puerta de enlace de API
Azure API Management resuelve las necesidades de API Gateway y Management, como el registro, la seguridad, la medición, etc. En este caso, cuando se usa un producto como Azure API Management, el hecho de que puede tener una sola puerta de enlace de API no es tan arriesgada porque estos tipos de puertas de enlace de API son "más delgados", lo que significa que no implementa código de C# personalizado que podría evolucionar hacia un componente monolítico.
Los productos de API Gateway suelen actuar como un proxy inverso para la comunicación de entrada, donde también puede filtrar las API de los microservicios internos además de aplicar autorización a las API publicadas en una sola capa.
La información proporcionada por un sistema de gestión de API le ayuda a comprender cómo se utilizan sus API y cómo están funcionando. Hacen esta actividad al permitirle ver informes de análisis casi en tiempo real e identificar tendencias que podrían afectar a su negocio. Además, puede tener registros sobre la actividad de solicitud y respuesta para un análisis más en línea y sin conexión.
Con Azure API Management, puede proteger las API mediante una clave, un token y el filtrado de IP. Estas características permiten aplicar cuotas y límites de velocidad flexibles y específicos, modificar la forma y el comportamiento de las API mediante directivas y mejorar el rendimiento con el almacenamiento en caché de respuestas.
En esta guía y la aplicación de ejemplo de referencia (eShopOnContainers), la arquitectura se limita a una arquitectura en contenedores más sencilla y personalizada para centrarse en contenedores sin formato sin usar productos PaaS como Azure API Management. Pero para aplicaciones de microservicio de gran tamaño que se implementan en Microsoft Azure, le animamos a evaluar Azure API Management como base para las puertas de enlace de API en producción.
Ocelote
Ocelot es una puerta de enlace de API ligera, recomendada para enfoques más sencillos. Ocelot es una puerta de enlace de API basada en .NET Core de código abierto especialmente creada para arquitecturas de microservicios que necesitan puntos unificados de entrada en sus sistemas. Es ligero, rápido y escalable y proporciona enrutamiento y autenticación entre muchas otras características.
La razón principal para elegir Ocelot para la aplicación de referencia eShopOnContainers 2.0 es porque Ocelot es una puerta de enlace de API ligera de .NET Core que puede implementar en el mismo entorno de implementación de aplicaciones donde va a implementar los microservicios o contenedores, como un host de Docker, Kubernetes, etc. Y como se basa en .NET Core, es multiplataforma que le permite implementar en Linux o Windows.
Los diagramas anteriores que muestran puertas de enlace de API personalizadas que se ejecutan en contenedores son precisamente cómo puede ejecutar Ocelot en una aplicación basada en contenedores y microservicios.
Además, hay otros muchos productos en el mercado que ofrecen características de puertas de enlace de API, como Apigee, Kong, MuleSoft o WSO2, y otros productos, como Linkerd y Istio, para características de controlador de ingreso de malla de servicio.
Después de las secciones de explicación de patrones y arquitectura iniciales, las secciones siguientes explican cómo implementar puertas de enlace de API con Ocelot.
Desventajas del patrón de puerta de enlace de API
El inconveniente más importante es que, al implementar una puerta de enlace de API, se acopla ese nivel con los microservicios internos. El acoplamiento como este podría suponer graves dificultades para la aplicación. Clemens Vaster, arquitecto del equipo de Azure Service Bus, hace referencia a esta posible dificultad como "la nueva ESB" en la sesión "Mensajería y microservicios" en GOTO 2016.
El uso de una puerta de enlace de API de microservicios crea un posible punto de error adicional.
Una pasarela de API puede provocar un incremento en el tiempo de respuesta debido a la llamada de red adicional. Pero esta llamada adicional suele tener menor impacto que una interfaz de cliente que realiza demasiadas llamadas a los microservicios internos.
Si no se escala horizontalmente de manera correcta, la puerta de enlace de API puede dar lugar a un cuello de botella.
Una puerta de enlace de API requiere un costo de desarrollo adicional y un mantenimiento futuro si incluye lógica personalizada y agregación de datos. Los desarrolladores deben actualizar la puerta de enlace de API para exponer los puntos de conexión de cada microservicio. Además, los cambios de implementación en los microservicios internos pueden provocar cambios de código en el nivel de puerta de enlace de API. Sin embargo, si la puerta de enlace de API solo aplica seguridad, registro y control de versiones (como cuando se usa Azure API Management), es posible que este costo de desarrollo adicional no se aplique.
Si la puerta de enlace de API ha sido desarrollada por un único equipo, puede haber un cuello de botella de desarrollo. Este aspecto es otro motivo por el que un mejor enfoque es tener varias puertas de enlace de API específicas definidas que responden a diferentes necesidades de cliente. También puede separar la puerta de enlace de API internamente en varias áreas o capas que pertenecen a los distintos equipos que trabajan en los microservicios internos.
Recursos adicionales
Chris Kemp. Pattern: API Gateway / Backend for Front-End (Patrón: puerta de enlace de API o back-end para front-end)
https://microservices.io/patterns/apigateway.htmlPatrón de puerta de enlace de API
https://learn.microsoft.com/azure/architecture/microservices/gatewayPatrón de agregación y composición
https://microservices.io/patterns/data/api-composition.htmlAzure API Management
https://azure.microsoft.com/services/api-management/Udi Dahan. Composición orientada a servicios
https://udidahan.com/2014/07/30/service-oriented-composition-with-video/Clemens Vasters. Mensajería y microservicios en GOTO 2016 (vídeo)
https://www.youtube.com/watch?v=rXi5CLjIQ9kPuerta de enlace API en pocas palabras (serie de tutoriales de puerta de enlace de API de ASP.NET Core)
https://www.pogsdotnet.com/2018/08/api-gateway-in-nutshell.html