Este artículo es una introducción al desarrollo de aplicaciones basadas en microservicios y a su gestión. Describe el diseño arquitectónico y los enfoques de implementación utilizando .NET Core y contenedores Docker. Este artículo fue escrito para los desarrolladores de .NET y los arquitectos de soluciones que están tratando de tomar una decisión sobre la arquitectura de su aplicación y no están familiarizados con la arquitectura basada en microservicios. En este artículo conocerá las ventajas de implementar una arquitectura basada en microservicios en lugar de desarrollar una aplicación monolítica y los enfoques para resolver los principales problemas que puede encontrar debido a este enfoque.
El patrón de diseño de microservicios promueve el desarrollo de aplicaciones complejas como un número de pequeñas partes independientes (servicios), que responden a las necesidades del negocio. Cada microservicio es responsable de una función específica del sistema.
En lugar de una aplicación monolítica, los microservicios pueden alojarse en diferentes lugares y los desarrolladores pueden realizar algunos cambios importantes en tiempo real, sin detener todo el sistema.
¿Por qué los microservicios en lugar de la arquitectura monolítica?
Durante mucho tiempo, el coste, el tiempo y la complejidad del aprovisionamiento de nuevo hardware han afectado de forma inequívoca al desarrollo de aplicaciones. Dado que las aplicaciones se escribieron para tener un tamaño estático y se diseñaron para un hardware específico, cuando la carga hacía que una aplicación superara su hardware, la respuesta era simplemente “escalar”, o actualizar el hardware de la aplicación para añadir capacidad, para evitar la reconfiguración del centro de datos y la refactorización del software.
El modelo de aplicación monolítica era limitado e ineficiente. Cambiar cualquier parte de la aplicación podía costar mucho tiempo y provocar un error en cualquier lugar de todo el sistema. En este caso, los desarrolladores debían depurar una enorme base de código para averiguar qué había salido mal. Cualquier característica recién entregada puede destruirlo todo durante un tiempo.
Las empresas intentan cada vez más resolver algunos problemas, cuando utilizan grandes aplicaciones corporativas para satisfacer sus propias necesidades:
- ahorrar costes
- hacer menos doloroso el proceso de despliegue
- mejorar el DevOps
Estos problemas pueden resolverse utilizando la arquitectura de microservicios en paridad con los contenedores. La contenedorización Docker se está convirtiendo en el estándar en el despliegue de aplicaciones. Las ventajas de la contenerización son una arquitectura flexible, ligera, segura, escalable y portátil. Con la ayuda de Kubernetes, puede desplegar y alojar fácilmente sus contenedores, gestionar cargas de trabajo y servicios en contenedores.
En este caso, cuando tenga una aplicación muy cargada, no necesitará escalar toda la aplicación, como debería hacerse en caso de utilizar una arquitectura monolítica. Puede escalar sólo unos pocos microservicios que tengan la mayor carga y mejorar su rendimiento con un consumo mínimo de recursos.
Arquitectura de microservicios Pros y Contras
La arquitectura de microservicios es un enfoque para construir una aplicación de servidor como un conjunto de pequeños servicios. Cada servicio debe ejecutarse dentro de su propio proceso y comunicarse con otros servicios utilizando protocolos como HTTP/HTTPS, WebSockets, etc. Cualquier parte de esta estructura (significa servicio) debe desarrollarse como una unidad autónoma, que puede desplegarse de forma independiente. Cada microservicio debe poseer su modelo de datos de dominio y su lógica de dominio relacionados y puede basarse en diferentes tecnologías de almacenamiento de datos. Por cierto, puede estar escrito en diferentes lenguajes de programación.
El punto principal durante el desarrollo de los microservicios es crear servicios débilmente acoplados, para proporcionar capacidades de despliegue, escalado y desarrollo independientes de cada servicio en la aplicación. Si hablamos del tamaño de los microservicios, debemos intentar que sean lo más pequeños posible, pero dejándolos con un mínimo de dependencias directas de otros microservicios. Esto proporciona agilidad a largo plazo, escalabilidad y mejor mantenimiento en el futuro.
La construcción de una arquitectura basada en microservicios de grano fino permite las prácticas de integración continua (CI) y entrega continua (CD). Da la oportunidad de integrar fácilmente nuevas características en aplicaciones que ya están en producción. Puede cambiar por completo uno de los microservicios para implementar una nueva funcionalidad o incluso romper este servicio, y no se romperá todo el sistema que ha construido.
Por último, puede añadir pruebas unitarias a cada microservicio y esto le dará la oportunidad de detectar fácilmente cualquier problema o error en su sistema antes de que pase a producción. En este caso, no necesita comprobar toda la aplicación, sólo debe depurar una pequeña parte del código: el microservicio actual.
Crear con éxito una aplicación de microservicios completa y desplegarla en la plataforma específica para la gestión de microservicios significa que tendrá algunos beneficios, como la eficiencia de costes, la escalabilidad y la disponibilidad 24/7. Mantener los microservicios sanos puede alcanzarse moviendo las instancias a VMs o servidores sanos por la plataforma. Así, cuando el software o el hardware en el que se ejecutan falla o debe reiniciarse para realizar actualizaciones, el sistema los traslada automáticamente al lugar seguro donde estos microservicios pueden seguir funcionando con éxito. Por cierto, los microservicios se pueden escalar de la misma manera, simplemente copiando el servicio a la nueva máquina virtual e iniciando una instancia más.
Plataformas, que pueden utilizarse para alojar y gestionar sus microservicios:
- Kubernetes
- Mesosphere DCOS
- Docker Swarm y Docker Compose
- OpenShift
- Pivotal Cloud Foundry
- Service Fabric
Todas estas plataformas pueden utilizarse con éxito para ejecutar su aplicación en la infraestructura de Azure sin ningún problema ni solución específica. Gestionar, escalar, desplegar y desarrollar fácilmente los microservicios, ¿no es una revolución en el desarrollo de aplicaciones?
Problemas y soluciones para la gestión de datos distribuidos
1. Cómo definir los límites de cada microservicio
El primer problema que se encuentra cuando se intenta crear una arquitectura de microservicios es definir los límites de los mismos. Cada servicio debe ser autónomo y seguir siendo una pieza de todo el sistema. Debe guardar todos los beneficios que la infraestructura de microservicios puede proporcionar.
Debe centrarse en los modelos de dominio lógico y en los datos relacionados. Intente identificar las islas de datos desacopladas y los diferentes contextos dentro de la misma aplicación. Estos contextos deben gestionarse y definirse por separado
2. Cómo crear consultas que recuperen datos de varios microservicios
El problema es que se trata de evitar que el cliente haga referencia directa a diferentes servicios. Especialmente cuando la aplicación del cliente debe llamar a diferentes microservicios API para realizar una tarea. Por ejemplo, cuando necesita obtener un rol de usuario (servicio de Seguridad) y el historial de pedidos (servicio de Pedidos). Enviar diferentes peticiones para realizar una acción puede ser una solución realmente mala.
Las formas más populares de evitar este problema son
- Crear una pasarela de la API para recibir todas las peticiones de los clientes y distribuir las peticiones en otros servicios. Incluso si alguno de sus microservicios necesita obtener algunos datos de otro microservicio, puede enviar una solicitud al microservicio de la pasarela. Esta petición será redirigida al receptor adecuado.
- CQRS con tablas de consulta/lectura. Esta solución consiste en agregar datos de múltiples microservicios utilizando el patrón de Vista Materializada. En este caso, sólo se genera una tabla de sólo lectura con los datos que son propiedad de diferentes microservicios. Esta tabla tiene un formato que debe recibir el cliente.
3. Cómo diseñar la comunicación a través de los límites de los microservicios
Otro problema que debe resolver es la comunicación. Un enfoque popular es utilizar microservicios basados en HTTP, lo cual es perfectamente aceptable. Es una buena idea utilizar esta solución para interactuar con el API Gateway o con diferentes microservicios. Pero existe cierto riesgo porque puede crear una cadena excesivamente larga de llamadas HTTP que puede convertir su aplicación basada en microservicios en algo monolítico y perder todas sus ventajas.
Por qué las API Gateways son mejores que la comunicación directa con los microservicios
Cuando desarrolla una aplicación, no puede predecir nada. Debe construir una arquitectura que pueda ser fácilmente escalada, mejorada o modificada. Si tiene peticiones directas de los clientes a sus microservicios, cualquier actualización de la respuesta de su microservicio puede provocar errores. Los clientes deben ser actualizados para utilizar diferentes puntos finales o recibir una respuesta en diferentes formatos. Si utiliza API Gateway, cualquier cambio en los microservicios no afectará a sus clientes de ninguna manera. Sólo debe cambiar la configuración de la pasarela para utilizar nuevos puntos finales u obtener una nueva respuesta. O incluso cambiar las nuevas respuestas al formato que los clientes utilizaban antes.
Por último, si utiliza la comunicación directa, puede encontrarse con los siguientes problemas:
- Acoplamiento. Las aplicaciones cliente deben saber dónde y cómo obtener los datos que necesitan. Debe tener enlaces directos con los servicios que pueden proporcionar la información necesaria.
- Demasiados viajes de ida y vuelta. Si tiene que llamar a diferentes microservicios para realizar una acción, puede obtener algunos viajes de ida y vuelta de red múltiples y una latencia significativa. Esto puede causar problemas de rendimiento.
- Problemas de seguridad. En caso de utilizar la comunicación directa, debe abrir sus microservicios al mundo, para dar a los clientes la posibilidad de utilizar su aplicación. En caso de utilizar API Gateway, puede hacer que sus microservicios sean accesibles sólo desde el microservicio Gateway. Es una forma más segura.
- Preocupaciones transversales. Cualquiera de sus microservicios que tenga comunicaciones directas con un cliente debe tener alguna lógica para comprobar la autorización, obtener los roles y permisos de los usuarios, etc. Puede causar problemas de rendimiento. En caso de utilizar Gateway, esta comprobación de permisos debería estar sólo en el microservicio Gateway.
Resumen
La selección de la arquitectura adecuada para la aplicación es una de las decisiones más valiosas para crear soluciones de calidad, de alto rendimiento y optimizadas. Y hay muchos factores de riesgo que debe tener en cuenta.
Monolítico | Microservicios | |
Gestión de datos | Puede utilizar un solo almacenamiento para los datos de toda la aplicación | Distribuidos. Debe encontrar una forma de aislar sus microservicios entre sí o encontrar una forma de sincronizar los datos entre ellos |
Desarrollo | Todos los miembros del equipo deben estar familiarizados con toda la arquitectura de la aplicación | Cada servicio puede ser desarrollado de forma independiente, por diferentes equipos |
Despliegue | Se puede desplegar y escalar sólo la aplicación completa | Cada servicio puede desplegarse de forma independiente. Puede escalar sólo los servicios que necesita y gastar menos dinero |
Obtención de datos | Puede obtener los datos que desee con una simple consulta | Debe encontrar la forma de recopilar datos de diferentes microservicios |
Costos | Gastará más dinero en caso de escalar su aplicación | El alojamiento independiente de cada servicio puede ahorrar costes |
La solución depende del tamaño de su aplicación. La arquitectura de aplicación monolítica puede ser una buena idea para aplicaciones pequeñas y ligeras. Pero no es realmente buena para aplicaciones complejas o en evolución. Es mucho más fácil construir una arquitectura monolítica al principio del desarrollo de la aplicación. Pero en el futuro, en caso de evolución, ampliación de la funcionalidad, la continuación del desarrollo le dará más problemas y gastará más dinero. Si necesita escalar su aplicación, en caso de ser monolítica, deberá escalar toda la enorme instancia de su aplicación. En caso de una arquitectura basada en microservicios, puede escalar sólo unos pocos microservicios y ahorrar sus costes.
Entonces, ¿qué preferir, microservicios o monolítica? La respuesta es bastante sencilla: si tiene una aplicación pequeña o ligera, puede utilizar la arquitectura monolítica para construir su sistema de forma realmente rápida. Pero si trata de crear algo grande – debe preferir la arquitectura basada en microservicios.