En 2021 inicié un apasionante proyecto de transformación digital, proceso que puedo decir que este año culmina. Tiene como punto de partida un sistema monolítico, junto con otros satélite que lo acompañan (también monolitos), sistema que no permite alcanzar los objetivos empresariales por sus limitaciones frente las exigencias actuales del negocio.
Se establecieron 2 vectores de cambio (la modernización de aplicaciones y las aplicaciones compuestas). Ambos están íntimamente relacionados y requieren de la provisión de un elemento central sobre el que pivotar: los microservicios. Veamos qué son y cómo pueden ayudarnos.
¿Qué es un microservicio?
Los microservicios son una colección de unidades funcionales concretas, pequeñas, independientes, acopladas débilmente, que se comunican mediante protocolos ligeros y que trabajan juntas para ofrecer la funcionalidad general de una aplicación, conformando una tipología o estilo de arquitectura distribuida donde cada servicio se ejecuta en su propio proceso.
Esencialmente, cada microservicio tiene una tarea específica y un objetivo limitado; son pequeños «ladrillos», cada uno con un propósito único, para construir «edificios» más grandes.
En este tipo de arquitecturas buscamos 4 objetivos fundamentales:
- agilidad de desarrollo y velocidad de entrega (al reducir el tamaño y alcance de los componentes).
- flexibilidad de despliegue.
- escalabilidad precisa.
- reutilización de funcionalidades, no de código.
Así pues cumplen, perfectamente, con las características que le requeríamos a las aplicaciones compuestas
¿En qué se diferencia de un monolito?
El monolito es una aplicación grande, unificada, mientras que la arquitectura de microservicios es una colección de unidades funcionales pequeñas que trabajan juntas.
El monolito es un gran edificio donde todo está integrado, autocontenido, en una misma estructura y construido con los mismos materiales y el mismo equipo. Reformar una partre del edificio supone afectar a toda o a parte dela estrucurta del mismo. A medida que se hace más grande, se vuelve difícil de mantener, lento para renovar y si el cimiento falla, todo el edificio se viene abajo.
Una aplicación compuesta basada en microservicios es un conjunto de pequeñas casas donde cada una es independiente y tiene su propia función. Hay una casa para los «pedidos», otra para los «clientes», otra para los «pagos», etc. Si quieres cambiar la casa de «pedidos», solo tienes que trabajar en esa casa, sin afectar a las otras casas del vecindario. Esto permite renovar las casas pequeñas mucho más rápido; si una casa se quema (un fallo), el resto del vecindario sigue (resiliencia) y, si hay mucha demanda en la casa de «pagos», puedes construir más casas de pagos sin tocar las de «clientes» o «pedidos».
Características
Podemos decir que los microservicios:
- Se organizan (deberían) entorno al DDD.
- Requieren de aislamiento en cuanto a los datos que manejan y lógica de negocio, no compartiendo BBDD con otros servicios ni lógica de negocio.
- Requieren afinar el nivel de granularidad.
- Son testeables, desplegables, reemplazables y escalables de forma independiente.
- Presentan bajo acoplamiento, alta cohesión y siguen el principio de responsabilidad única.
- Interoperan entre ellos (síncrona o asíncronamente) a través de interfaces, no de «puertas traseras» a los datos.
- Son resilientes; si un servicio falla, el resto seguirá funcionando.
- Son independientes del lenguaje y tecnologías.
- Son productos, no proyectos.
- No tienen estado.
Tipología
Puede ser variopinta; no me atrevería a decir que hay una de universal. Me gusta decir que los hay de los siguientes tipos, reflejando una separación clara de preocupaciones:
- De Canal: optimizan el consumo de los microservicios por parte de una interfaz de usuario específica. Son un backend intermedio que transforma y agrega datos del core de la aplicación (los servicios de Negocio y Coordinación) para satisfacer exactamente las necesidades de un canal específico (web, iOS, Android, TV, etc.). Implementan la lógica de mapeo de datos y presentación necesaria para ese canal. Desacoplan el desarrollo del frontend del desarrollo del backend, permitiendo que ambos avancen a su propio ritmo.
- De Coordinación: garantizan la consistencia transaccional y la ejecución de flujos de negocio que abarcan múltiples servicios (sí, lo sé, una gran desventaja respecto de lo que ocurre en un monolito, donde sí tienes garantizada la transaccionalidad). Actúan como orquestador o motor de flujo de trabajo. Reciben una solicitud de alto nivel (ej. «Realizar Compra») y envían comandos secuenciales a los Servicios de Negocio. No contienen reglas de negocio funcional. Su única lógica es la gestión del flujo. Centralizan la complejidad del flujo distribuido.
- De Negocio (Dominio): aplican las reglas de negocio y manteienen la integridad del dominio. Son el corazón de la aplicación. Cada uno implementa un dominio o subdominio de negocio específico (ej.
InventoryService,CustomerService,OrderService). Acceden directamente a su propia base de datos, lo que les otorga autonomía completa. Son eutilizables y deben adherirse estrictamente al Principio de Responsabilidad Única. Permiten la evolución, escalabilidad y despliegue completamente independientes de las funcionalidades esenciales del negocio. - De Integración: Aislan y protegen el modelo de dominio interno de la empresa de las influencias y complejidades de los sistemas externos o legacy. Traducen los datos, protocolos y conceptos del sistema externo al modelo de dominio del nuevo sistema de microservicios. Es el único que interactúa con el sistema externo. Si el sistema externo cambia su protocolo o formato de datos, solo hay que actualizar el Servicio de Integración, sin modificar todos los Servicios de Negocio. Aísla el riesgo tecnológico y protege los Servicios de Negocio de la «corrupción» de modelos de datos incompatibles o tecnologías obsoletas.
Retos
No todo es una maravilla. Usa los microservicios introducen una serie de retos técnicos y organizacionales significativos que deben ser gestionados cuidadosamente.
Retos Técnicos y Operacionales
- Comunicación: pasar de una simple llamada local a una función a una llamada por red introduce latencia y la necesidad de gestionar fallos de red.
- Observabilidad: se necesitan herramientas avanzadas para la monitorización, trazabilidad y el log para diagnosticar problemas.
- Consistencia (Transacciones): se pierde la facilidad de las transacciones ACID (Atómicas, Consistentes, Aisladas, Duraderas) de una base de datos central. Se debe adoptar la Consistencia Eventual y patrones complejos para emular transacciones, lo que añade complejidad.
- Gestión de la Infraestructura y el Despliegue: en lugar de desplegar una única aplicación, se deben desplegar decenas o cientos de servicios. Esto requiere la adopción de tecnologías de orquestación de contenedores, y la inversión en pipelines de CI/CD (Integración y Despliegue Continuos) totalmente automatizados.
- Seguridad: la seguridad se vuelve más compleja; hay que asegurar no solo el punto de entrada (tráfico norte-sur), sino también las comunicaciones internas (tráfico este-oeste) entre los microservicios, a menudo requiriendo autenticación de servicio a servicio y gestión centralizada de secretos.
- Pruebas: probar la funcionalidad de un extremo a otro requiere configurar y ejecutar el entorno distribuido completo, lo cual es más complejo que las pruebas de integración en un monolito.
Retos Organizacionales y Culturales
- Ley de Conway y estructura de equipos: la arquitectura de microservicios solo funciona si la estructura de la organización la soporta. Los equipos deben ser pequeños, autónomos y responsables de sus servicios de principio a fin, lo cual a menudo requiere una reestructuración de los equipos a equipos separados por servicio o dominio de negocio.
- Gobernanaza y estandarización: el riesgo de la proliferación tecnológica (cada equipo elige una tecnología diferente) es alto. Se necesita establecer una gobernanza ligera sobre estándares de comunicación, logging, seguridad y herramientas.
- Mayor «overhead» de comunicación: los equipos necesitan una coordinación constante a nivel contratos de APIs y eventos para evitar rupturas entre servicios.
- Curva de aprendizaje: la arquitectura distribuida tiene una curva de aprendizaje empinada que requiere una inversión significativa en capacitación del personal.
Conclusión
Moverse hacia una arquitectura distribuida con microservicios representa una transformación estratégica para las organizaciones, convirtiendo la complejidad monolítica rígida en una complejidad distribuida más manejable a escala, pero con retos de calado.
Debemos verlo como una inversión necesaria en complejidad operativa para lograr una ventaja competitiva en la agilidad. Permite a la empresa innovar más rápido, escalar las funcionalidades de manera independiente y construir sistemas más resilientes. Sin embargo, esta transición exige un cambio cultural y una alta inversión en automatización, observabilidad y herramientas para gestionar la nueva complejidad de la comunicación en red y la consistencia de datos